swift - 自定义中缀运算符和选项
问题描述
class TreeNode: Equatable {
static func ==(lhs: TreeNode, rhs: TreeNode) -> Bool {
lhs.val == rhs.val && lhs.left == rhs.right && lhs.right == rhs.left
}
var val: Int = 0
var left, right: TreeNode?
}
这段代码可以编译,甚至可以工作。但为什么?left
和right
变量是可选的,我不应该先在正文中解开它static func ==
吗?
其实这不是一个等式。如您所见,它是某种对称方程。因此,我想为此目的定义具有不同名称的自定义运算符:
infix operator =|=: ComparisonPrecedence
class TreeNode {
static func =|=(lhs: TreeNode, rhs: TreeNode) -> Bool {
lhs.val == rhs.val && lhs.left =|= rhs.right && lhs.right =|= rhs.left
}
var val: Int = 0
var left, right: TreeNode?
}
由于我之前提到的原因,现在它无法编译。它希望我先打开选项。
实际上,如果它像“=="))) 那样“正常工作”,那就太好了,因为在这里不必显式地解开选项会很方便。
所以我想了解为什么它在这两种情况下表现不同。
解决方案
这段代码可以编译,甚至可以工作。但为什么?
这仅仅是因为为所有where is声明了一个==
运算符,如下所示:Optional<Wrapped>
Wrapped
Equatable
static func == (lhs: Wrapped?, rhs: Wrapped?) -> Bool
TreeNode
在Equatable
你的第一个代码片段中,所以它可以工作。
在您的第二个代码片段中,您尚未声明=|=
对 two 进行操作的运算符TreeNode?
。您可以通过将其置于全局范围内来做到这一点......
func =|= (lhs: TreeNode?, rhs: TreeNode?) -> Bool {
switch (lhs, rhs) {
case (nil, nil): // both nil
return true
case (let x?, let y?): // both non-nil
return x =|= y // compare two non-optional tree nodes
default:
return false
}
}
或写一个Optional
扩展:
extension Optional where Wrapped == TreeNode {
static func =|= (lhs: Wrapped?, rhs: Wrapped?) -> Bool {
switch (lhs, rhs) {
case (nil, nil): // both nil
return true
case (let x?, let y?): // both non-nil
return x =|= y // compare two non-optional tree nodes
default:
return false
}
}
}
但正如 Leo Dabus 所说,我只会遵守Equatable
而不是创建自己的运营商。符合现有协议允许您使用TreeNode
标准库中的许多 API,例如Array.contains(_:)
.
推荐阅读
- c# - 连接字符串错误“缺少其语句块”
- python - DataFrame.from_dict 无法将带有元组键的 dict 更改为多索引数据帧
- ios - 无法将“UIViewController”类型的值转换为另一个视图控制器
- arrays - 从 grep 输出创建关联数组
- python - Python - 将 JSON 对象传递给函数时附加到 JSON 对象的附加“成员”
- python - 我可以为循环中的 for 循环制作的图像分配一个变量吗?
- python-3.x - 我正在尝试将一些文本放在我想要的 PDF 位置。但它不在正确的位置
- java - 获取特定行的 SQLite android
- scala - 在 Spark 中将数据框列转换为向量
- json - 无法在 curl 命令上将正文读取为 JSON 对象