当相等运算符可以时,为什么Swift的大于或小于运算符不能比较可选项? [英] Why can't Swift's greater-than or less-than operators compare optionals when the equality operators can?
问题描述
在Swift 3中,如果我使用>
或<
In Swift 3, this is a compile error, if I use >
or <
let a: Int?
guard a > 0 else {return}
guard a < 0 else {return}
编译错误:
可选类型'Int?'的值没有包装;你的意思是使用'!'还是?"?
Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?
但是,如果我将==
或!=
But it's okay if I compare with ==
or !=
let a: Int?
guard a == 0 else {return}
guard a != 0 else {return}
推荐答案
对于相等运算符来说,支持可选值是很有意义的,因为对于任何整数值变量i
:
It makes perfect sense for the equality operator to support optionals, because it's absolutely clear that for any integer valued variable i
:
-
nil == nil
-
nil != i
-
i != nil
-
i == i
当且仅当它们的值相同时
nil == nil
nil != i
i != nil
i == i
if and only if their values are the same
另一方面,尚不清楚与nil
的比较应如何发挥作用:
On the other hand, it's not clear how comparison to nil
should act:
i
小于nil
吗?
- 如果我想对数组进行排序以使所有
nil
都出现在末尾,那么我希望i
小于nil
. - 但是如果我想对数组进行排序以使所有
nil
都在开始时出现,那么我希望i
大于nil
.
- If I want to sort an array so that all the
nil
s come out at the end, then I would wanti
to be less thannil
. - But if I want to sort an array so that all the
nil
s come out at the start, then I would wanti
to be greater thannil
.
由于这两个都是同等有效的,因此标准库偏向于另一个就没有意义.留给程序员来实现对他们的用例有意义的比较.
Since either of these are equally valid, it wouldn't make sense for the standard library to favor one over the other. It's left to the programmer to implement whichever comparison makes sense for their use-case.
这是一个玩具实现,它生成一个比较运算符来适应两种情况:
Here's a toy implementation that generates a comparison operator to suite either case:
func nilComparator<T: Comparable>(nilIsLess: Bool) -> (T?, T?) -> Bool {
return {
switch ($0, $1) {
case (nil, nil): return true
case (nil, _?): return nilIsLess
case (_?, nil): return !nilIsLess
case let (a?, b?): return a < b
}
}
}
let input = (0...10).enumerated().map {
$0.offset % 2 == 0 ? 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?]
Input: [0?, nil, 2?, nil, 4?, nil, 6?, nil, 8?, nil, 10?]
nil小于:[nil,nil,nil,nil,nil,0?,2?,4?,6?,8?,10?]
nil is less: [nil, nil, nil, nil, nil, 0?, 2?, 4?, 6?, 8?, 10?]
nil更大:[0?,2?,4?,6?,8?,10?,nil,nil,nil,nil,nil]
nil is more: [0?, 2?, 4?, 6?, 8?, 10?, nil, nil, nil, nil, nil]
这篇关于当相等运算符可以时,为什么Swift的大于或小于运算符不能比较可选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!