2017-12-02 188 views
0

我有一個Game類。我說它是通用的,因爲我需要支持不同類型的電路板。現在我只想添加一個經典的iOS風格的委託,其方法是將一個遊戲和一個新的積分值作爲參數。如何在Swift associatedtype的方式實現這一點?我很困惑,我無法推動這種簡單的邏輯。在通用類型的委託協議中使用associatedtype

protocol GamePointsDelegate { 
    associatedtype B: Board 
    func game(_ game: Game<B>, didSetPoints points: Int) 
} 

class Game<B: Board> { 
    let board: Board 

    var points = 0 { 
     // Compiler Error 
     // Member 'game' cannot be used on value of protocol type 'GamePointsDelegate'; use a generic constraint instead 
     didSet { pointsDelegate?.game(self, didSetPoints: points) } 
    } 

    // Compiler Error 
    // Protocol 'GamePointsDelegate' can only be used as a generic constraint because it has Self or associated type requirements 
    var pointsDelegate: GamePointsDelegate? 
} 
+0

刪除相關類型並只使用泛型函數'game'是否可行? – Qbyte

+0

因爲'GamePointsDelegate'不是一個類型,所以你不能有'GamePointsDelegate'類型的'var pointsDelegate'。它就像一個類型的模板,它爲'B'的每個可能值產生一個新類型。 – Alexander

+0

@亞歷山大,我明白了。但是我在'Game'中已經有'B'了,我想以某種方式使用它。 – kelin

回答

1

你可以從協議中刪除相關類型的要求,使用一個通用的功能game代替:

protocol GamePointsDelegate { 
    func game<B>(_ game: Game<B>, didSetPoints points: Int) 
} 

所以,你可以用你的Game類的代碼,因爲它是,但缺點是,符合協議的類必須處理所有的Board

+1

這給了我一個警告:「冗餘一致性約束'B':'Board'」。但是如果我從泛型聲明中刪除'Board',一切都會編譯。謝謝! – kelin