簡體   English   中英

Swift:約束泛型參數以在更受約束的泛型函數中使用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM