[swift-evolution] [swift-users] [swift-user]Unexpected behavior of protocol extension.

Zhao Xin owenzx at gmail.com
Tue Sep 20 07:01:56 CDT 2016


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 <
swift-evolution at swift.org> 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 (
> swift-users at swift.org) 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
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160920/c46874d9/attachment.html>


More information about the swift-evolution mailing list