2017-12-02 187 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