一尘不染

当相等运算符可以时,为什么Swift的大于或小于运算符不能比较可选项?

swift

在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}

阅读 282

收藏
2020-07-07

共1个答案

一尘不染

对于相等运算符来说,支持可选值是很有意义的,因为对于任何整数值变量,这是绝对清楚的i

  • nil == nil
  • nil != i
  • i != nil
  • i == i 当且仅当它们的值相同时

另一方面,尚不清楚与的比较nil应如何起作用:

i小于nil

  • 如果我想对数组进行排序以使所有nils都在末尾出现,那么我希望i小于nil
  • 但是,如果我想对数组排序以便所有nils都在开始时出现,那么我希望i大于nil

由于这两种方法都同样有效,因此标准库偏one其中一个是没有意义的。留给程序员实施对于他们的用例有意义的比较。

这是一个玩具实现,可以生成一个比较运算符来适应两种情况:

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?]

nil小于:[nil,nil,nil,nil,nil,0?,2?,4?,6?,8?,10?]

nil更大:[0?,2?,4?,6?,8?,10?,nil,nil,nil,nil,nil]

2020-07-07