使Swift协议符合相关类型的Equatable
问题描述:
在Swift 2.1(运行XCode 7.2)中,我试图让协议的关联类型符合Equatable。使Swift协议符合相关类型的Equatable
// (#1)
/**
A Node in a graph
*/
public protocol GraphNode : Equatable {
typealias Content : Equatable
/**
The content of the node.
E.g. in a graph of strings, this is a string
*/
var content: Content {get}
/// The list of neighbours of this Node in the graph
var children: [Self] {get}
}
我们可以有一个定义不同类型的相关类型协议的非均质实现,我希望我将无法在这里定义(在协议层面,而不是在执行级)相等功能:
// (#2)
/// Won't compile, as expected
public func ==(lhs: GraphNode, rhs: GraphNode) {
return lhs.content == rhs.content
}
这是因为我没有保证lhs.Content
相同类型rhs.Content
。 不过,我希望我能有一些通用的约束指定,如:
// (#3)
/// Won't compile, why?
public func ==<Node1 : GraphNode, Node2 : GraphNode where Node1.Content == Node2.Content>(lhs: Node1, rhs: Node2)
{
return lhs.content == rhs.content // ERROR: Binary operator '==' cannot be applied to two 'Node1.Content' operands
}
在#3
,我们知道,无论LHS和RHS具有相同类型的,我们知道(从相关类型的规范如Equatable
)Content
是可以等化的。那为什么我不能比较它们呢?
答
添加-> Bool
。只是一个错误的错误信息。有时跨越多行编写函数声明并不会使其更具可读性。
public func ==<Node1 : GraphNode, Node2 : GraphNode where Node1.Content == Node2.Content>(lhs: Node1, rhs: Node2) -> Bool {
return (lhs.content == rhs.content)
}
谢谢,就是这样!有时你只需要第二双眼睛(或更好的汇编错误报告:)) – Marco83