Swift类型推理不起作用(Xcode 7.1.1)



这是我在StackOverflow上的第一个问题,所以请放心。

我一直在努力让Swift调用适当的泛型重载。

假设我有以下协议-

protocol MyProtocol { }

我有以下通用方法-

func foo<T>() -> T
func foo<T: MyProtocol>() -> T

可以预期,用符合MyProtocol的返回类型T调用foo()将调用适当的重载。

let bar: MyProtocol = foo()

上面的代码实际上在运行时调用了以下函数,IDE中的Cmd+Click也会导航到错误的重载。

func foo<T>() -> T

由于某些原因,我无法在Xcode 7.1.1中正常工作。

我是在这里错过了一些完全基本的东西,还是这是斯威夫特的另一个怪癖?

编辑

根据matt的请求添加一个该行为的示例。

protocol MyProtocol { }
class MyProtoClass : MyProtocol { }
class Bar {
    func foo<T>(value: T) {
        print("T is Generic")
    }
    func foo(value: MyProtocol) {
        print("T conforms to MyProtocol")
    }
}
class MyClass<T> {
    var value: T
    init(value: T) { self.value = value }
    var b = Bar()
    func print() {
        b.foo(value)
    }
}
MyClass<MyProtocol>(value: MyProtoClass()).print()
MyClass<String>(value: "").print()

将上面的代码复制并粘贴到Swift命令行应用程序中并执行会产生以下输出。

T is Generic
T is Generic

我认为这里的问题是泛型中的协议(通常是Swift中的协议)不能按照你想要的方式工作。它们不是一流的类型。我知道这很模糊。。。但从这个角度来看;如果删除foofunc foo<T>(value: T)版本,则代码甚至无法编译。换言之,斯威夫特没有选择foo,也没有选错;就是说CCD_ 7不调用CCD_。

我有一种模糊的感觉,这与我在这里的问题有关:

协议没有';不符合自己吗?

好的,我将在这里回答我自己的问题。

经过一些调查,Swift似乎希望您在泛型参数上实现一个具有类型约束的扩展。

extension MyClass where T : MyProtocol {
    func print() {
        b.foo(value)
    }
}

我知道这并不能真正解决问题,但对于我来说,在现实世界的用例中,这已经足够了。

上面的样本最终会看起来像下面这样。

protocol MyProtocol { }
class MyProtoClass : MyProtocol { }
class Bar {
    func foo<T>(value: T) {
        print("T is Generic")
    }
    func foo(value: MyProtocol) {
        print("T conforms to MyProtocol")
    }
}
class MyClass<T> {
    var value: T
    init(value: T) { self.value = value }
    var b = Bar()
    func print() {
        b.foo(value)
    }
}
extension MyClass where T : MyProtocol {
    func print() {
        b.foo(value)
    }
}
MyClass<MyProtoClass>(value: MyProtoClass()).print()
MyClass<String>(value: "").print()

相关内容

最新更新