以下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)'
在代码段return protX.foo(x)
中。
这可能看起来像一个人为的例子,但它已经从我现有的现实问题中减少了。
如果我尝试按照错误消息中的建议,我得到:
'Self' is only available in a protocol or as the result of a method in a class;
did you mean 'Test'?
如何才能进行打字检查?
答案 0 :(得分:1)
您已让编译器无理由相信Workflow.ItemClass
与函数ProtocolX.ItemClass
中的test(_:x:)
类型相同。如果您要求ItemClass
函数的test
类型参数与函数中的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)
}
}