类型向下转换无法在Swift

时间:2017-10-19 09:20:08

标签: swift generics

我发现Swift类在完成类型向下转换时无法调用原始方法。

AFAIK,同样的事情可以通过类指针在C / C ++中完成。

让代码谈谈:

protocol MyProtocol {
    func log()
}

class MyClass: MyProtocol {
}

class MyGenericClass<T>{
    init(_ t: T) {}
}

extension MyGenericClass: MyProtocol {
    func log() {
        print("MyGenericClass MyProtocol")
    }
}

extension MyGenericClass where T==Int {
    func log() {
        print("MyGenericClass<Int>")
    }
}

extension MyProtocol {
    func log() {
        print("MyProtocol")
    }
}
extension MyProtocol where Self==TestSwift.MyGenericClass<Int> {
    func log() {
        print("MyProtocol where MyGenericClass<Int>")
    }
}

extension MyProtocol where Self==MyClass {
    func log() {
        print("MyProtocol where MyClass")
    }
}

func logByProtocol(_ p: MyProtocol) {
    p.log()
    print("Type of p is: \(type(of: p))")
}

let myGenericClassNumber = MyGenericClass(1)
let myGenericClassString = MyGenericClass("1")
let myClass = MyClass()


myGenericClassNumber.log()//expect "MyGenericClass<Int>"
myGenericClassString.log()//expect "MyGenericClass MyProtocol"
myClass.log()//expect "MyProtocol where MyClass"

logByProtocol(myGenericClassNumber)//expect "MyGenericClass<Int>", BUT "MyGenericClass MyProtocol"
logByProtocol(myGenericClassString)//expect "MyGenericClass MyProtocol"
logByProtocol(myClass)//expect "MyProtocol where MyClass"

我希望logByProtocol(myGenericClassNumber)会打印"MyGenericClass<Int>",但会打印&#34; MyGenericClass MyProtocol&#34;。

似乎MyGenericClass<Int>无法找到原始的log()方法,同时将其向下转换为MyProtocol类型。

如何解决这个问题,使"down"类可以调用其原始方法?

1 个答案:

答案 0 :(得分:0)

这是因为Swift dynamic dispatch忽略了这个通用约束:

MyGenericClass where T==Int

并在此分机上发送呼叫:

extension MyGenericClass: MyProtocol {}

我正在谈论的动态调度是你编写logByProtocol(_)方法的地方;这是使用动态调度来调用log()方法。

为什么这个

myGenericClassNumber.log()

按预期工作是因为它是log()对象上的静态调度MyGenericClass<Int>方法。