Thank you to Игорь Никитин and Adrian Zubarev. Now I can convince myself for this behavior.
As Adrian's example shows, there is no `bar()` implemented in `class A`, so there is no `override func bar()` in class B`. My thought that `self.bar()` would do the same as `(self as! B).bar()`, is called "dynamic binding", which is basing on the `override`. Since there is no `override`, there is no "dynamic binding". I thought "dynamic binding" was basing on dynamic type of `self`. It was not. I was wrong. The behavior is clear now. In class A's `self.bar()`, the runtime finds that there is no implementation of `bar()` in `class A`, so it calls the `bar` in protocol extension. In class A's `(self as! B).bar()`, as `class B` contains the implementation of `bar()`, the runtime calls it. Zhaoxin On Tue, Sep 20, 2016 at 4:21 PM, Adrian Zubarev via swift-evolution < [email protected]> wrote: > I can’t tell you the reason, but to me it feels like it’s doing the > following thing: > > + - - (Type: B) - - + > | | > | func bar() + - + (Type: A) - - + < - - - - - - - > - - - - - - - - - - - - - + > | | | > | > + - - - - - - - + func output() + - + (Protocol: Foo) - - + — - self.bar() - > + - (self as! B).bar() - + > | | | > | > + - - - - - - - + (default) func bar() | <- - - - - - - - > + > | | > + - - - - - - - - - - - - + > > class A:Foo { > > func bar() {} > > func output() { > print(type(of:self)) > self.bar() > (self as! B).bar() > } > } > > class B:A { > > override func bar() { > print("I am B.") > } > } > > Would solve this temporarily. > > And there we are again with the same discussion if custom implementation > of protocol members, which have default implementation, should have the > override keyword or not. > > Imagine your code like this (not valid code): > > protocol Foo { > func bar() > } > > extension Foo { > func bar() { > print("I am bar.") > } > } > > class A : Foo { > > func output() { > > print(type(of:self)) > default.bar() // fallback an call directly the default implementation > whenever needed > self.bar() // will print "I am bar." on A().output() but should print > "I am B." if Self == B > (self as! B).bar() > } > } > > class B : A { > > override func bar() { > print("I am B.") > } > } > > I still think default implementations should be called through something > like default. + whenever you override a default implementation you’d need > override. There is a discussion going on: Mark protocol methods with > their protocol. I clearly did not solved your issue, but I might have > wake your interest to participate. ;) > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 20. September 2016 um 04:13:22, Zhao Xin via swift-users ( > [email protected]) schrieb: > > See below code. > > protocol Foo { > > func bar() > > } > > > extension Foo { > > func bar() { > > print("I am bar.") > > } > > } > > > class A:Foo { > > func output() { > > print(type(of:self)) // prints "B". > > self.bar() // prints "I am bar." > > (self as! B).bar() // prints "I am B." > > } > > } > > > class B:A { > > func bar() { > > print("I am B.") > > } > > } > > > let b = B() > > b.output() > > > I thought `self.bar()` would do the same as `(self as! B).bar()`. It > didn't. In my opinion, `type(of:self) is B.type`, so they should be the > same, shouldn't they? > > > Zhaoxin > _______________________________________________ > swift-users mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-users > > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
