泛型函数内的 Swift Equatable 泛型类型比较
Posted
技术标签:
【中文标题】泛型函数内的 Swift Equatable 泛型类型比较【英文标题】:Swift Equatable Generic type comparison inside generic function 【发布时间】:2017-09-04 22:31:33 【问题描述】:我有一个像这样的二叉树的Node
类:
class Node<T: Equatable>
let value: T
let left: Node<T>?
let right: Node<T>?
init(value: T, left: Node<T>? = nil, right: Node<T>? = nil)
self.value = value
self.left = left
self.right = right
这些值需要是相等的。
我可以这样测试公平性:
let a = Node(value: 8)
let b = Node(value: 7)
let c = a.value > b.value
效果很好,c: true
但是当我编写一个使用节点公平性的通用函数时,我得到了错误:
func isBinaryTree<T>(node: Node<T>) -> Bool
if let leftNode = node.left
guard leftNode.value < node.value else
return false
guard isBinaryTree(node: leftNode) else
return false
if let rightNode = node.right
guard rightNode.value >= node.value else
return false
guard isBinaryTree(node: rightNode) else
return false
return true
let result = isBinaryTree(node: root)
错误:
error: binary operator '<' cannot be applied to two 'T' operands guard leftNode.value < node.value ||`
我不确定为什么编译器似乎不知道为什么 T
值是 Equatable
或者为什么它不认为 leftNode
上的 T
与T
node
。
代码:
let d = Node(value: Float(3), left: Node(value: Int(8)) , right: nil)
按预期给出错误。
进一步研究,它与函数无关,因为当我尝试代码时:
let x = Node(value: 3, left: Node(value: 8) , right: nil)
let y = x.value < x.left!.value
我遇到同样的错误
【问题讨论】:
你的例子c
不可能,因为你的Node
不是Comparable
。
我觉得把Equatable
和Comparable
混在一起真的很傻。谢谢!
您真正需要的是Comparable
协议。 Equatable
协议只需要实现相等 (==
) 函数即可实现一致性。比较函数(如<
)只保证由Comparable
协议实现。
@richy 在像这样的任意树中,它的可比性没有任何意义。您应该只访问value
并比较它们
【参考方案1】:
在一般情况下,两个 Node
对象是不可比较的。这取决于它们所在的树的类型。例如,如果节点仅被限制为二叉树的有效成员,这是有道理的,但事实并非如此。
幸运的是,您不需要将Node
设为Comparable
,您只需要将其value
设为Comparable
:
class Node<T: Comparable>
let value: T
let left: Node<T>?
let right: Node<T>?
init(value: T, left: Node<T>? = nil, right: Node<T>? = nil)
self.value = value
self.left = left
self.right = right
extension Node: Equatable
static func == (lhs: Node, rhs: Node) -> Bool
return lhs.value == rhs.value
&& lhs.left == rhs.left
&& lhs.right == rhs.right
extension Node
func isBinarySubTree() -> Bool
return left.map $0.value < self.value ?? true
&& right.map self.value < $0.value ?? true
&& left?.isBinaryTree() ?? true
&& right?.isBinaryTree() ?? true
【讨论】:
【参考方案2】:感谢 Alexander,我的 Equatable
和 Comparable
搞混了!节点应该是
class Node<T: Comparable>
//...
代码:
let a = Node(value: 8)
let b = Node(value: 7)
let c = a.value > b.value
必须工作,因为编译器知道值是Int
s。但在函数中,输入值是未知的。
【讨论】:
以上是关于泛型函数内的 Swift Equatable 泛型类型比较的主要内容,如果未能解决你的问题,请参考以下文章