![](/img/trans.png)
[英]How to pass protocol with associated type (generic protocol) as parameter in Swift?
[英]How to call a generic function with parameter of associated type in Swift 3
這是我的示例代碼:
protocol P {
}
protocol B {
associatedtype ID: P
}
class MyClass: B {
enum ID: P {
case one
case two
}
}
func process<T: B>(_ value: T.ID) {
// do something
}
process(MyClass.ID.one) // Compile Error: cannot convert value of type 'MyClass.ID' to expected argument type '_.ID'
如您所見,我使用參數定義泛型函數,該參數的類型是泛型類型 T的關聯類型 。 我怎么稱呼這個功能? 我想使用MyClass.ID.one作為參數,但編譯器提供以下警告:
cannot convert value of type 'MyClass.ID' to expected argument type '_.ID'
看來Swift通過從MyClass.ID
開始為T.ID
並且支持MyClass
為T
從調用中推斷出T
是一個問題。
如果您更改函數以獲取類型T
的附加參數,則代碼將編譯並運行正常:
func process<T: B>(_ value: T.ID, _ workaround : T) {
// do something
}
let workaround = MyClass()
process(MyClass.ID.one, workaround)
Swift設計人員可以通過兩種方式解決這個推理問題:
T
看來他們決定使用Swift 4的第二種方法,因為原始函數無法編譯,發出以下錯誤:
通用參數
'T'
未在函數簽名中使用
更好的解決方法是使用Java風格的方法傳遞類型而不是實例:
func process<T: B>(_ value: T.ID, _ workaround: T.Type) {
// do something
}
...
process(MyClass.ID.one, MyClass.self)
dasblinkenlight為您當前實現無效的原因提供了一個很好的答案。 如果決定的解決方案是簡單地找到另一種方法來實現這個功能,那么我會選擇一個不那么hacky的解決方案:
extension B {
static func process(_ value: Self.ID) {
//do stuff
}
}
MyClass.process(.one)
這利用了通過協議擴展Self
實現的更靈活的類型推斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.