2016-08-20 103 views
4

我想強制關聯類型爲Self,但編譯器沒有它。
這裏就是我想要去編譯:Swift Self作爲綁定在協議中的關聯類型

protocol Protocol { 
    // Error: Inheritance from non-protocol, non-class type 'Self' 
    associatedtype Type: Self 
} 

你可能會問,爲什麼不使用Self代替相關類型的?僅僅因爲我不能:關聯類型是從父協議繼承的。在父協議中改變它是沒有意義的。
下面是類似我想要做一些事情:

protocol Factory { 
    associatedtype Type 

    func new() -> Type 
} 

protocol SelfFactory: Factory { 
    associatedtype Type: Self // Same Error 
} 

編輯:
馬特的答案几乎是什麼我要找的。它的行爲就像我在運行時所希望的那樣,但在編譯時沒有足夠的限制。
我想這是不可能的:

protocol Factory { 
    associatedtype MyType 
    static func new() -> MyType 
} 

protocol SelfFactory: Factory { 
    static func new() -> Self 
} 

final class Class: SelfFactory { 

    // Implement SelfFactory: 
    static func new() -> Class { 
     return Class() 
    } 

    // But make the Factory implementation diverge: 
    typealias MyType = Int 

    static func new() -> Int { 
     return 0 
    } 
} 

我想Classtypealias觸發重新聲明錯誤或相似。

+0

錯誤消息是絕對正確的。用你的話來說明問題的根源:「關聯類型是從父協議繼承的」。不,它不是。協議不做「繼承」。你似乎無法像另一個協議那樣「覆蓋」一個協議。你要麼採用協議,要麼你不這樣做。 – matt

+0

「我想在類中的typealias觸發重新聲明錯誤或類似的」你不能防止超載! 'f() - > Int'和'f() - > String'可以在Swift中共存。你在問語言是不同的語言。你不是編譯器。換句話說,採用協議並不妨礙我實施協議所不需要的其他方法! – matt

+0

目前還不清楚你想要什麼,爲什麼。什麼會讓你滿意?也許你最好的選擇是有兩個_unrelated_協議,Factory和SelfFactory。我只採用它們。 _that_會讓你開心嗎? (但是當然,即使那樣你也不能阻止我採用他們兩個,如果我覺得這樣的話)。 – matt

回答

3

你想說這個嗎?

protocol Factory { 
    associatedtype MyType 
    func new() -> MyType 
} 

protocol SelfFactory: Factory { 
    func new() -> Self 
} 
+0

這幾乎是我所追求的。我編輯了更多細節的問題。謝謝回答! – ThinkChaos

+0

在花費更多時間與此抗爭之後,我相信這是目前最好的解決方案。我希望能夠說'SelfFactory'的'Factory'的實現是「最終的」,但我想這不會發生。不得不重複每個功能定義都很煩人,但是哦。 – ThinkChaos

+0

實際上,如果我將'SelfFactory'定義爲空協議,並在擴展中實現'new'方法,這仍然可行。 – ThinkChaos

2

我意識到這是一個老問題,但你可以做到這一點作爲Swift 4.0

protocol Factory { 
    associatedtype MyType 
    static func new() -> MyType 
} 

protocol SelfFactory: Factory where MyType == Self { } 

是不是where子句很大?