繁体   English   中英

符合性要求中的类型不引用泛型参数或关联类型

[英]Type in conformance requirement does not refer to a generic parameter or associated type

在 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 }
}

我可以实现的协议扩展Fightable提供的共享实现fight跨越这符合所有的值类型Stats ,如果我改变的类型签名fight

func fight (other: Self) -> Bool

并实现扩展为

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

上述实现的问题在于它要求值类型相同( Human无法与Goblin对抗)。 我现在的目标是实现一个协议扩展,它提供的默认实现fight ,只要它们实现统计值类型的任意组合。

以下代码

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

产生错误

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

我如何确保其他 Fightable 类型也符合此扩展的 Stats?

我正在使用 Xcode 7 beta 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
    }
}

对我有用的一种方法是在您的 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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM