Swift协议函数重载

4

在处理协议类型时,是否可能重载协议函数并调用正确的定义?

以下是一些代码,用于说明此问题。

protocol SomeProtocol {
    func doSomething<T>(obj: T)
}

class SomeClass : SomeProtocol {
    func doSomething<T>(obj: T) {
        print("Generic Method")
    }
    func doSomething(obj: String) {
        print(obj)
    }
}

let testClass = SomeClass()

testClass.doSomething("I will use the string specific method")
(testClass as SomeProtocol).doSomething("But I will use the generic method")

编辑:为澄清起见,代码是有效的。我想知道为什么两个调用都没有使用字符串特定方法。

双重编辑:删除了一个中间调度类作为更简单的示例

这是一个错误、当前限制还是预期功能?如果是有意的,请有人解释一下为什么?

Swift 2.0,Xcode 7.0

答案

您不能重载协议函数并期望调用正确的定义。这是因为在编译时选择要调用的定义。由于编译器不知道具体类型,因此它选择在编译时唯一已知的定义doSomething<T>


我在游乐场中运行了这段代码,它正常工作:我将使用特定方法\n通用方法 - vikingosegundo
1
代码可以运行。我对为什么两个调用都没有使用特定的方法感到困惑。 - eunoia
两种方法都被使用。 - vikingosegundo
1
指特定的方法,我指的是非通用的、带有字符串参数的方法。 - eunoia
你需要强制编译器将第二个字符串视为“SomeProtocol”,这样它才能调用不太具体的版本。 - vikingosegundo
1个回答

1
我在http://swiftstub.com/这里测试了你的代码,它正常运行。首先会打印出"I will use the specific method",然后是"Generic Method":

I will use the specific methodGeneric Method


这就是我困惑的地方。为什么它们不都使用特定的方法? - eunoia
我认为这是因为方法dispatcher.dispatch(testClass, obj: "But I will use the generic method")接收一个泛型作为参数,并将其作为泛型类型传递给方法doSomething<T>(obj: T)。也许编译器首先检查参数是否为泛型,然后决定调用哪个方法。在这种情况下,testClass.doSomething("I will use the specific method")的参数直接是一个字符串。而在这种情况下,dispatcher.dispatch(testClass, obj: "But I will use the generic method")也是一个字符串,但作为泛型类型传递。 - Chuy47
这很有道理。实际上,Dispatch类的通用中介机制阻止编译器正确推断String类型。那么这是否意味着我正在尝试做的是不可能的?或者(未来的)更新编译器理论上可以推断出正确的类型吗? - eunoia
好的,在这个新的情况下(testClass作为SomeProtocol)。doSomething("But I will use the generic method"),你正在使用testClass作为SomeProtocol,并且someProtocol只有具有通用类型的方法,这就是为什么调用了具有通用类型的方法。 - Chuy47
是的,正如你所说,它似乎在编译时被选中了。 - Chuy47
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接