如何约束泛型函数关联类型
How to constrain generic function associated types
我正在尝试采用两个具有相同关联类型和 return 相同类型的协议,但运气不佳。
protocol MyProtocol {
associatedtype AssociatedType
}
func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
where T.AssociatedType == R.AssociatedType {
return arg //Error-> Cannot convert return expression of type 'T' to return type 'R'
}
在 Swift 中有这样的可能吗?
两种类型(称它们为 T
和 R
)不一定等同,只是因为它们遵循相同的协议并使用相同的关联类型。
根据这个推理,Array<Int>
与 Set<Int>
相同,应该可以自由互换,因为它们都符合 Collection
,其中 Element
是 Int
.
这是另一个反例:
protocol MyProtocol {
associatedtype AssociatedType
init()
}
protocol MySubProtocol1: MyProtocol where AssociatedType == Int {}
protocol MySubProtocol2: MyProtocol where AssociatedType == Int {}
struct S1: MySubProtocol1 {}
struct S2: MySubProtocol2 {}
func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
where T.AssociatedType == R.AssociatedType {
return arg as! R // Let's see what would happen. Don't do this!
}
func produce<T: MySubProtocol1>(type: T.Type) -> T {
return T()
}
func consume<T: MySubProtocol2>(arg: T, ofType: T.Type) {
print(arg)
}
consume(arg: myFunc(arg: produce(type: S1.self)), ofType: S2.self)
Terminated due to signal: ABORT TRAP (6)
Could not cast value of type 'main.S1'
(0x100e44210
) to 'main.S2'
(0x100e44228
).
我正在尝试采用两个具有相同关联类型和 return 相同类型的协议,但运气不佳。
protocol MyProtocol {
associatedtype AssociatedType
}
func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
where T.AssociatedType == R.AssociatedType {
return arg //Error-> Cannot convert return expression of type 'T' to return type 'R'
}
在 Swift 中有这样的可能吗?
两种类型(称它们为 T
和 R
)不一定等同,只是因为它们遵循相同的协议并使用相同的关联类型。
根据这个推理,Array<Int>
与 Set<Int>
相同,应该可以自由互换,因为它们都符合 Collection
,其中 Element
是 Int
.
这是另一个反例:
protocol MyProtocol {
associatedtype AssociatedType
init()
}
protocol MySubProtocol1: MyProtocol where AssociatedType == Int {}
protocol MySubProtocol2: MyProtocol where AssociatedType == Int {}
struct S1: MySubProtocol1 {}
struct S2: MySubProtocol2 {}
func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
where T.AssociatedType == R.AssociatedType {
return arg as! R // Let's see what would happen. Don't do this!
}
func produce<T: MySubProtocol1>(type: T.Type) -> T {
return T()
}
func consume<T: MySubProtocol2>(arg: T, ofType: T.Type) {
print(arg)
}
consume(arg: myFunc(arg: produce(type: S1.self)), ofType: S2.self)
Terminated due to signal:
ABORT TRAP (6)
Could not cast value of type
'main.S1'
(0x100e44210
) to'main.S2'
(0x100e44228
).