[英]Swift: constrain a generic parameter for use in a more constrained generic function
我正在實現一個需要符合如下協議的類:
protocol P {
func magic<T>(_ thing: Thing, as type: T.Type) -> T
}
此協議由第三方代碼提供,這意味着我無法以任何方式更改它以解決此問題。
現在,我有一個通用函數
func magicForObject<T: AnyObject>(_ thing: Thing, as type: T.Type) -> T
我想從我的magic
實現中調用它,只是為了輸入的thing
,它們實際上是對象。 也就是說,我想做這樣的事情:
func magic<T>(_ thing: Thing, as type: T.Type) -> T {
if T.self is AnyClass {
return magicForObject(thing, as: type)
}
else {
// do something else
}
}
但我找不到任何方法來完成這項工作。 上面的代碼顯然不能編譯,類似的東西也不能編譯
if let T_ = T.self as? AnyClass { ... }
因為T_
只是一個普通變量,而不是一個通用參數(大概是編譯時)。
我也試過這樣做:
func magic<T: AnyObject>(_ thing: Thing, as type: T.Type) -> T { ... }
func magic<T>(_ thing: Thing, as type: T.Type) -> T { ... }
並分別實施兩者。 如果直接在對象上調用此函數,則會正確調用受約束的AnyObject
,但在將對象AnyObject
為協議類型P
時則不會,在這種情況下,始終使用第二個。
這種情況似乎無可救葯地受到限制,但有沒有我沒有想到的解決方法?
看起來這在 Swift 中目前是不可能的。 我在 Swift 論壇上發表了一篇文章來宣傳這個想法; 如果這也是您需要的東西,請隨時加入。
你的例子有點難以使用,所以我不得不做很多假設,但我想這應該滿足你的要求。
根據您所說的,您有一個給定的協議 P:
protocol P {
func magic<T>(_ thing: Thing, as type: T.Type) -> T
}
讓我們給 P 一個你需要它做的默認實現:
extension P {
// Implementation for magic where T is a class
func magic<T>(_ thing: Thing, as type: T.Type) -> T where T: AnyObject {
print("AnyObject Called")
return Test2() as! T
}
// Implementation for magic where T is a struct
func magic<T>(_ thing: Thing, as type: T.Type) -> T {
print("Struct Called")
return Test() as! T
}
}
你有一個符合 P 的類
class Test2: P {
}
讓我們假設你有這個 Thing 對象和一個我們想要傳遞的結構,看看我們是否有正確的結果:
class Thing {
}
struct Test {
}
現在讓我們測試一下我們是否在Test2
上調用magic
是否會根據傳遞給magic
type
調用正確的函數
let test = Test()
let test2 = Test2()
// T is Test2 so its a class
test2.magic(Thing(), as: Test2.self)
// T is Test so its a struct
test2.magic(Thing(), as: Test.self)
打印輸出調用
AnyObject Called
Struct Called
看起來你可以為structs
做一些事情,而為classes
做另一件事
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.