这是我关于StackOverflow的第一个问题,所以请放轻松我。
我一直在努力让Swift调用适当的泛型重载。
假设我有以下协议 -
=IF(B1="", "", IF(ISNUMBER(SEARCH("*FIG*", B1)), "FIG", IF(ISNUMBER(SEARCH("*SF*", B1)), "SF", IF(ISNUMBER(SEARCH("*AF*", B1)), "AF&L", IF((ISNUMBER(SEARCH("*IB*", B1))), IF(ISNUMBER(SEARCH("*ASIA*", B1)), "IBAsia", "IBexA"))))))
我有以下通用方法 -
protocol MyProtocol { }
可以预期,使用符合func foo<T>() -> T
func foo<T: MyProtocol>() -> T
的返回类型foo()
调用T
会调用适当的重载。
MyProtocol
上面的代码实际上在运行时调用了以下函数,IDE中的Cmd + Click也导航到了错误的重载。
let bar: MyProtocol = foo()
出于某种原因,我无法在Xcode 7.1.1中正常使用它。
我是否遗漏了一些完全基本的东西,或者这是另一个斯威夫特的怪癖?
修改
根据matt的请求添加此行为的示例。
func foo<T>() -> T
将上述代码复制并粘贴到Swift命令行应用程序中并执行产生以下输出。
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()
答案 0 :(得分:1)
我认为这里的问题是泛型中的协议(通常在Swift中)不能按照您希望的方式工作。他们不是一流的类型。我知道这很模糊......但是这样看待它;如果你删除了func foo<T>(value: T)
foo
版本,你的代码甚至都不会编译。换句话说,Swift没有选择foo
并选择错误;它说b.foo(a1.value)
不会调用func foo<T: MyProtocol>(value: T)
。
我有一种模糊的感觉,这与我的问题有关:
答案 1 :(得分:0)
好的,我将在这里回答我自己的问题。
经过一些调查后,似乎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()