2

来自维基百科

与传统的相等运算符不同,它将根据参数是否相等或不相等返回真或假,宇宙飞船运算符将根据左参数相对于右参数的值返回 1、0 或 -1。如果左参数大于右参数,则运算符返回 1。如果左参数小于右参数,则运算符返回 -1。如果两个参数相等,则运算符返回 0。

spaceship 运算符主要用于排序中的比较。

4

3 回答 3

13

Swift 没有内置的 spaceship 运算符,但在 swift 中创建新的运算符很简单。让我们创建一个返回 anenum而不是 an的新运算符Int——幻数不好的,我们不应该将它们用于强类型语言中的返回类型。在此过程中,让我们利用 Swift 的 Unicode 支持,并使用 ←、→ 和 ↔ 使枚举支持结果的可视指示符:

enum Spaceship
{
  case ← // LeftIsGreaterThanRight
  case → // LeftIsLessThanRight
  case ↔ // LeftIsEqualToRight
}

operator infix <=> {}

@infix func <=> <T: Comparable> (left: T, right: T) -> Spaceship {
  if left < right { return SpaceShip.→}
  if left > right { return SpaceShip.←}
  return Spaceship.↔;
}

现在您可以像这样使用 new 运算符

if someInt <=> someOtherInt == ←
{
  // take off!
}

如果你坚持使用幻数作为比较结果值(我真的非常非常鼓励你不要在 Swift 中这样做),那么在这里:

@infix func <=><T: Comparable> (left: T, right: T) -> Int {
  if left < right { return -1 }
  if left > right { return  1 }
  return 0
}
于 2014-06-06T16:40:46.940 回答
3

不,Swift 目前不包括宇宙飞船操作员。

用于 Swift 的自定义 Spaceship Operator

可以定义自定义运算符以模仿其他语言中的宇宙飞船运算符的外观和功能。

运营商

由于 Swift 允许在自定义运算符中使用<,=>字符,我们可以定义一个自定义运算符,如下所示<=>

使用运算符

该运算符是二元中缀运算符,用法如下:

1 <=> 2   //Returns: -1
2 <=> 1   //Returns: 1
1 <=> 1   //Returns: 0

定义运算符

运算符可以像这样在 Swift 中定义:

operator infix <=> {}

@infix func <=><T: Comparable> (left: T, right: T) -> Int {
  if left < right { return -1 }
  if left > right { return  1 }
  return 0
}
于 2014-06-06T14:09:05.640 回答
0

正如一些ComparisonResult已经存在的那样,可以使用:

extension Comparable {
    static func <=> (lhs: Self, rhs: Self) -> ComparisonResult {
        if lhs < rhs { return .orderedAscending }
        if lhs > rhs { return .orderedDescending }
        return .orderedSame
    }
}

如问题中所述:

spaceship 运算符主要用于排序中的比较。

这是双重事实,因为它甚至可以用于在其他函数之上实现Sequence优雅的稳定排序函数:

extension Sequence {
    func sorted(with comparator: (Element, Element) throws -> ComparisonResult) rethrows -> [Element]
    {
        return try enumerated()
            .sorted { (try comparator($0.element, $1.element) || $0.offset <=> $1.offset) == .orderedAscending }
            .map { $0.element }
    }
}

extension ComparisonResult {
    static func || (lhs: Self, rhs: @autoclosure () -> Self) -> ComparisonResult {
        if lhs == .orderedSame {
            return rhs()
        }
        return lhs
    }
}
于 2022-02-17T19:41:46.243 回答