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

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Sep 20 03:21:30 CDT 2016


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160920/20767f57/attachment.html>


More information about the swift-evolution mailing list