一致性要求中的类型不引用泛型参数或关联类型
Type in conformance requirement does not refer to a generic parameter or associated type
在Swift2中我有以下协议
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
}
}
上面实现的问题在于它要求值类型必须相同(Human
s不能打Goblin
s)。我目前的目标是实现一个协议扩展,为任何值类型的组合提供 fight
的默认实现,只要它们实现 Stats.
如下代码
extension Fightable where Fightable : Stats {
func fight (other: Fightable) -> Bool {
return self.defense > other.attack
}
}
产生错误
Type 'Fightable' in conformance requirement does not refer to a generic parameter or associated type
如何确保其他 Fightable 类型也符合此扩展的统计信息?
我正在使用 Xcode 7 beta 1。
对我有用的一种方法是在您的 Fightable 协议中创建类型别名。所以你可以在你的协议扩展中约束 fight 函数的参数。由于这种情况,您还必须使战斗功能通用(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
}
}
对不起,我误解了你的问题。因此,如果我对你的理解是正确的(希望如此),则不可能通过协议扩展(至少在这些约束下)获得 fight
函数的默认实现。因为如果你想要 other
符合 Fightable
和 Stats
它不再是以前的函数,其中 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
}
}
在Swift2中我有以下协议
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
}
}
上面实现的问题在于它要求值类型必须相同(Human
s不能打Goblin
s)。我目前的目标是实现一个协议扩展,为任何值类型的组合提供 fight
的默认实现,只要它们实现 Stats.
如下代码
extension Fightable where Fightable : Stats {
func fight (other: Fightable) -> Bool {
return self.defense > other.attack
}
}
产生错误
Type 'Fightable' in conformance requirement does not refer to a generic parameter or associated type
如何确保其他 Fightable 类型也符合此扩展的统计信息?
我正在使用 Xcode 7 beta 1。
对我有用的一种方法是在您的 Fightable 协议中创建类型别名。所以你可以在你的协议扩展中约束 fight 函数的参数。由于这种情况,您还必须使战斗功能通用(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
}
}
对不起,我误解了你的问题。因此,如果我对你的理解是正确的(希望如此),则不可能通过协议扩展(至少在这些约束下)获得 fight
函数的默认实现。因为如果你想要 other
符合 Fightable
和 Stats
它不再是以前的函数,其中 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
}
}