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

时间:2017-06-28 16:48:06

标签: swift optional

在Swift 3中,如果我使用><

,这是编译错误
let a: Int?
guard a > 0 else {return}
guard a < 0 else {return}

编译错误:

  

可选类型的值&#39; Int?&#39;没有打开;你的意思是使用&#39;!&#39;或者&#39;?&#39;?


但是,如果我与==!=

进行比较,那就没问题了
let a: Int?
guard a == 0 else {return}
guard a != 0 else {return}

3 个答案:

答案 0 :(得分:4)

对于等式运算符来说,支持选项是非常有意义的,因为对于任何整数值变量i来说,它是绝对清楚的:

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

另一方面,不清楚与nil的比较应如何行事:

i是否小于nil

  • 如果我想对数组进行排序以便最后显示所有nil,那么我希望i小于nil
  • 但是,如果我想对数组进行排序,以便所有nil在开始时出现,那么我希望i大于nil

由于其中任何一个都同样有效,因此标准库不利于其他标准库是有意义的。它留给程序员来实现对他们的用例有意义的任何比较。

这是一个玩具实现,它生成一个比较运算符以适应任何一种情况:

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]

答案 1 :(得分:1)

可选的相等性在逻辑上起作用,比较不起作用。

  • !=
  • 5 == 5 = true
  • 5 == nil = false
  • 5 == 6 = false

这些都是有道理的,但这些不是:

  • nil == nil = true
  • 6 > 5 = true
  • 5 > 5 = false
  • 5 > nil = ??

这种比较没有简单的答案,根据用例,答案也不一样。

答案 2 :(得分:0)

这是因为IntInt?是两件不同的事情。

根据documentationInt<>以及其他一些运算符的重载,而Optional只有==和{{}的重载1}},请参阅documentation on Optional,该部分讨论比较可选值