为啥 Swift 的大于或小于运算符不能比较可选项,而相等运算符可以呢?
Posted
技术标签:
【中文标题】为啥 Swift 的大于或小于运算符不能比较可选项,而相等运算符可以呢?【英文标题】:Why can't Swift's greater-than or less-than operators compare optionals when the equality operators can?为什么 Swift 的大于或小于运算符不能比较可选项,而相等运算符可以呢? 【发布时间】:2017-06-28 16:48:06 【问题描述】:在 Swift 3 中,如果我使用 >
或 <
,这是一个编译错误
let a: Int?
guard a > 0 else return
guard a < 0 else return
编译错误:
可选类型“Int?”的值未拆封;你的意思是用'!'还是“?”?
但如果我与==
或!=
进行比较,就可以了
let a: Int?
guard a == 0 else return
guard a != 0 else return
【问题讨论】:
您希望nil < 0
评估为什么? -1 < nil
怎么样?目前尚不清楚这些病例应如何处理。有了nil == 0
,它的含义就一目了然了。
比较***.com/q/39251005/2976878
提案:Remove Optional Comparison Operators。此外,这一定是个骗局。
也相关:***.com/questions/39427650/….
【参考方案1】:
等式运算符支持可选项是非常有意义的,因为绝对清楚对于任何整数值变量i
:
nil == nil
nil != i
i != nil
i == i
当且仅当它们的值相同时
另一方面,与nil
的比较应该如何发挥作用尚不清楚:
i
是否小于 nil
?
nil
s 出现在最后,那么我希望i
小于nil
。
但是,如果我想对数组进行排序,以便所有nil
s 从一开始就出现,那么我希望i
大于nil
。
由于其中任何一个都同样有效,因此标准库偏爱其中一个是没有意义的。由程序员来实现对他们的用例有意义的任何比较。
这是一个玩具实现,它生成一个比较运算符来适应任何一种情况:
func nilComparator<T: Comparable>(nilIsLess: Bool) -> (T?, T?) -> Bool
return
switch ($0, $1)
case (nil, nil): return false
case (nil, _?): return nilIsLess
case (_?, nil): return !nilIsLess
case let (a?, b?): return a < b
let input = (0...10).enumerated().map
$0.offset.isMultiple(of: 2) ? Optional($0.element) : nil
func concisePrint<T>(_ optionals: [T?]) -> String
return "[" + optionals.map $0.map "\($0)?" ?? "nil" .joined(separator: ", ") + "]"
print("Input:", concisePrint(input))
print("nil is less:", concisePrint(input.sorted(by: nilComparator(nilIsLess: true))))
print("nil is more:", concisePrint(input.sorted(by: nilComparator(nilIsLess: false))))
输出:
输入:
[0?, nil, 2?, nil, 4?, nil, 6?, nil, 8?, nil, 10?]
nil 小于:
[nil, nil, nil, nil, nil, 0?, 2?, 4?, 6?, 8?, 10?]
nil 更多:
[0?, 2?, 4?, 6?, 8?, 10?, nil, nil, nil, nil, nil]
【讨论】:
【参考方案2】:可选相等在逻辑上有效,而比较则无效。
5 == 5 = true
5 == nil = false
5 == 6 = false
nil == nil = true
这些都是有道理的,但这些都没有:
6 > 5 = true
5 > 5 = false
5 > nil = ??
nil > 5 = ??
这种类型的比较没有简单的答案,根据用例的不同,答案也不相同。
【讨论】:
5 > nil = nil
nil > 5 = nil
我希望在这种情况下返回类型是 Bool?,而不是 Bool【参考方案3】:
这是因为Int
和Int?
是两个不同的东西。
根据documentation,Int
有<
和>
等一些操作符的重载,而Optional只有==
和!=
的重载,见documentation on Optional部分谈论比较可选值。
【讨论】:
以上是关于为啥 Swift 的大于或小于运算符不能比较可选项,而相等运算符可以呢?的主要内容,如果未能解决你的问题,请参考以下文章