使Swift协议符合相关类型的Equatable

时间:2016-01-24 11:10:18

标签: swift

在Swift 2.1(运行XCode 7.2)中,我试图使一个具有相关类型的协议符合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.Contentrhs.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都具有相同的类型,并且我们知道(从关联类型的规范为EquatableContent是等同的。那么为什么我不能比较它们呢?

1 个答案:

答案 0 :(得分:1)

添加public func ==<Node1 : GraphNode, Node2 : GraphNode where Node1.Content == Node2.Content>(lhs: Node1, rhs: Node2) -> Bool { return (lhs.content == rhs.content) } 。只是一个错误的错误消息。有时在多行中编写函数声明并不会使它更具可读性。

$button-colors: (
  'red': (
    'base': #ff0000,
    'light': #ff1a1a,
    'dark': #800000
  ),
  'blue': (
    'base': #2457DD,
    'light': #3399ff,
    'dark': #003366
  ),
  'green': (
    'base': #00cc00,
    'light': #4DFF57,
    'dark': #187F09
  )
);