以下 Swift 代码:
class Workflow<ItemClass: Hashable> {
var block: (ItemClass -> Int)?
init() {}
}
protocol ProtocolX {
typealias ItemClass
func foo(x: ItemClass) -> Int
}
func test<Y: ProtocolX, ItemClass: Hashable>(protX: Y, x: ItemClass) {
let workflow = Workflow<ItemClass>()
workflow.block = { (x: ItemClass) in
return protX.foo(x)
}
}
因以下编译器错误而失败:
Cannot invoke 'foo' with an argument list of type '(ItemClass)':
Expected an argument list of type '(Self.ItemClass)'
在代码片段中返回protX.foo(x)
。
这可能看起来像是一个人为的例子,但它是从我遇到的现实世界问题中简化出来的。
如果我尝试遵循错误消息中的建议,我只会得到:
'Self' is only available in a protocol or as the result of a method in a class;
did you mean 'Test'?
如何对其进行类型检查?
最佳答案
您没有让编译器相信 Workflow.ItemClass
与函数 test(_:x:) 中的
。如果您的意思是要求 ProtocolX.ItemClass
类型相同test
函数的 ItemClass
类型参数与函数内的 ProtocolX.ItemClass
相同,您可以告诉编译器需要它,如下所示:
func test<Y: ProtocolX, ItemClass: Hashable where Y.ItemClass == ItemClass>(protX: Y, x: ItemClass) {
let workflow = Workflow<ItemClass>()
workflow.block = { (x: ItemClass) in
return protX.foo(x)
}
}
但是您可以完全消除单独的 ItemClass
参数:
func test<Y: ProtocolX where Y.ItemClass: Hashable>(protX: Y, x: Y.ItemClass) {
let workflow = Workflow<Y.ItemClass>()
workflow.block = { (x: Y.ItemClass) in
return protX.foo(x)
}
}
关于swift - 为什么这个 Swift 代码不进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35234473/