【问题标题】:Type in conformance requirement does not refer to a generic parameter or associated type符合要求的类型不是指泛型参数或关联类型
【发布时间】:2015-06-16 18:13:57
【问题描述】:

在 Swift 2 中,我有以下协议

protocol Fightable {
    // return true if still alive, false if died during fight
    func fight (other: Fightable) -> Bool
}

protocol Stats {
    var defense: Int { get }
    var attack: Int { get }
}

如果我将fight 的类型签名更改为

func fight (other: Self) -> Bool

并将扩展实现为

extension Fightable where Self : Stats {
    func fight (other: Self) -> Bool {
        return self.defense > other.attack
    }
}

上述实现的问题在于它要求值类型相同(Humans 无法对抗Goblins)。我目前的目标是实现一个协议扩展,只要它们实现了 Stats,它就为任何值类型组合提供fight 的默认实现。

以下代码

extension Fightable where Fightable : Stats {
    func fight (other: Fightable) -> Bool {
        return self.defense > other.attack
    }
}

产生错误

一致性要求中的“Fightable”类型不引用泛型参数或关联类型

如何确保其他 Fightable 类型也符合此扩展的统计信息?

我正在使用 Xcode 7 beta 1。

【问题讨论】:

    标签: swift generics interface swift2


    【解决方案1】:

    对不起,我误解了您的问题。因此,如果我理解正确(希望如此),则不可能通过协议扩展(至少在这些约束下)获得 fight 函数的默认实现。因为如果你想让other 符合FightableStats,那么它就不再是以前的函数了,other 可以是任何Fightable。所以它没有实现所需的功能。 作为解决方法,我建议(采用您现有的代码):

    protocol Fightable {
        // return true if still alive, false if died during fight
        func fight (other: Fightable) -> Bool
    }
    
    protocol Stats {
        var defense: Int { get }
        var attack: Int { get }
    }
    
    extension Fightable where Self : Stats {
        // directly conforming to the protocol
        func fight (other: Fightable) -> Bool {
            if let otherStat = other as? Stats {
                return self.defense > otherStat.attack
            }
            // providing a good way if other does not conform to Stats
            return false
        }
    }
    

    【讨论】:

      【解决方案2】:

      对我有用的一种方法是在您的 Fightable 协议中创建一个类型别名。所以你可以在你的协议扩展中限制战斗功能的参数。由于这种情况,您还必须使您的战斗功能通用(Fightable 不仅可以用作通用约束)。

      在代码中是这样的:

      protocol Fightable {
          // make typealias
          typealias F = Fightable
          // make function generic
          func fight<F: Fightable>(other: F) -> Bool
      }
      
      protocol Stats {
          var defense: Int { get }
          var attack: Int { get }
      }
      
      // constraint F and Self
      extension Fightable where F : Stats, Self: Stats {
          func fight(other: F) -> Bool {
              return self.defense > other.attack
          }
      }
      
      // example of an implementation
      struct Human: Fightable {
          func fight<F: Fightable>(other: F) -> Bool {
              return true
          }
      }
      

      【讨论】:

      • 这对我不起作用,因为您仍然必须为符合 Fightable 和 Stats 的结构实现战斗功能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多