当相等运算符可以时,为什么Swift的大于或小于运算符不能比较可选项? [英] Why can't Swift's greater-than or less-than operators compare optionals when the equality operators can?

查看:93
本文介绍了当相等运算符可以时,为什么Swift的大于或小于运算符不能比较可选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 nils come out at the end, then I would want i to be less than nil.
  • But if I want to sort an array so that all the nils come out at the start, then I would want i to be greater than nil.

由于这两个都是同等有效的,因此标准库偏向于另一个就没有意义.留给程序员来实现对他们的用例有意义的比较.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆