【问题标题】:Using associatedtype in a delegate protocol for a generic type在泛型类型的委托协议中使用关联类型
【发布时间】:2017-12-03 07:17:00
【问题描述】:

我有一个Game 课程。我把它做成通用的,因为我需要支持不同类型的板。现在我只想添加一个经典的 iOS 风格的委托,它带有一个将游戏和新的积分值作为参数的方法。如何以 Swift 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?
}

【问题讨论】:

  • 删除关联类型并只使用泛型函数game是否可行?
  • 您不能拥有GamePointsDelegate 类型的var pointsDelegate,因为GamePointsDelegate 不是一个类型。它就像一个类型的模板,它为B 的每个可能值生成一个新类型。
  • @Alexander,我明白了。但我已经在Game 中有B,我想以某种方式使用它。
  • @kelin 如果必须在GamePointsDelegate 中使用关联类型,那么Game 需要一个新的泛型参数,称为Delegate,类型为GamePointsDelegate 其中Self.Delegate.B == @ 987654336@.
  • @Alexander,感谢您的解释。我更喜欢泛型函数,因为它更简单。

标签: swift generics protocols associated-types


【解决方案1】:

您可以从协议中删除关联的类型要求,并改用通用函数 game

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

因此,您可以按原样使用 Game 类的代码,但缺点是符合协议的类必须处理所有 Boards。

【讨论】:

  • 这给了我一个警告:“冗余一致性约束'B':'Board'”。但是如果我从泛型声明中删除Board,一切都会编译。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多