小于或大于 Swift switch 语句

我熟悉 Swift 中的 switch语句,但不知道如何用 switch代替这段代码:

if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
82881 次浏览

这里有一个办法。假设 someVarInt或其他 Comparable,您可以选择将操作数赋给一个新变量。这使您可以使用 where关键字以任何方式对其进行范围界定:

var someVar = 3


switch someVar {
case let x where x < 0:
print("x is \(x)")
case let x where x == 0:
print("x is \(x)")
case let x where x > 0:
print("x is \(x)")
default:
print("this is impossible")
}

这可以简化一点:

switch someVar {
case _ where someVar < 0:
print("someVar is \(someVar)")
case 0:
print("someVar is 0")
case _ where someVar > 0:
print("someVar is \(someVar)")
default:
print("this is impossible")
}

你也可以通过范围匹配来完全避免使用 where关键字:

switch someVar {
case Int.min..<0:
print("someVar is \(someVar)")
case 0:
print("someVar is 0")
default:
print("someVar is \(someVar)")
}

因为有人已经张贴了 case let x where x < 0:这里是一个替代的 someVar是一个 Int

switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}

这里有一个 someVarDouble的替代方案:

case -(Double.infinity)...0: // do something
// etc

switch语句在底层使用 ~=操作符:

let x = 2


switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}

Desugars 这样说:

if 1          ~= x { print(1) }
else if 2     ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else {  }

如果您查看标准库引用,它可以准确地告诉您 ~=重载时要做什么 : 包括范围匹配和等价的事情。(不包括枚举大小写匹配,这是一种语言特性,而不是 std lib 中的函数)

您将看到它与左边的直布尔值不匹配。对于这类比较,您需要添加一个 where 语句。

除非... ... 您自己超载了 ~=操作符。(通常推荐使用 没有)一种可能性是这样的:

func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool {
return lhs(rhs)
}

这样就匹配了一个函数,该函数将左边的布尔值返回给右边的参数。你可以用它来做这些事情:

func isEven(n: Int) -> Bool { return n % 2 == 0 }


switch 2 {
case isEven: print("Even!")
default:     print("Odd!")
}

对于你的情况,你可能有一个这样的陈述:

switch someVar {
case isNegative: ...
case 0: ...
case isPositive: ...
}

但是现在您必须定义新的 isNegativeisPositive函数。

可以将普通中缀运算符重载为局部前缀或后缀运算符:

postfix operator < {}


postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool {
return lhs < rhs
}

事情是这样的:

let isGreaterThanFive = 5<


isGreaterThanFive(6) // true
isGreaterThanFive(5) // false

将这个函数与前面的函数结合起来,您的 switch 语句可以看起来如下:

switch someVar {
case 0< : print("Bigger than 0")
case 0  : print("0")
default : print("Less than 0")
}

现在,你可能不应该在实践中使用这种东西: 它有点危险。你(可能)最好还是坚持 where的说法。也就是说,开关语句模式

switch x {
case negative:
case 0:
case positive:
}

或者

switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}

看起来很普通,值得考虑。

你可以:

switch true {
case someVar < 0:
print("less than zero")
case someVar == 0:
print("eq 0")
default:
print("otherwise")
}

这是它看起来像与范围

switch average {
case 0..<40: //greater or equal than 0 and less than 40
return "T"
case 40..<55: //greater or equal than 40 and less than 55
return "D"
case 55..<70: //greater or equal than 55 and less than 70
return "P"
case 70..<80: //greater or equal than 70 and less than 80
return "A"
case 80..<90: //greater or equal than 80 and less than 90
return "E"
case 90...100: //greater or equal than 90 and less or equal than 100
return "O"
default:
return "Z"
}

<0表达式已经不起作用了(再也不起作用了?) ,所以我最终得出如下结论:

Swift 3.0:

switch someVar {
case 0:
// it's zero
case 0 ..< .greatestFiniteMagnitude:
// it's greater than zero
default:
// it's less than zero
}

使用 Swift 5,您可以选择以下开关之一来替换 if 语句。


# 1与 PartialRangeFromPartialRangeUpTo一起使用开关

let value = 1


switch value {
case 1...:
print("greater than zero")
case 0:
print("zero")
case ..<0:
print("less than zero")
default:
fatalError()
}

# 2与 ClosedRangeRange一起使用开关

let value = 1


switch value {
case 1 ... Int.max:
print("greater than zero")
case Int.min ..< 0:
print("less than zero")
case 0:
print("zero")
default:
fatalError()
}

# 3在 where 子句中使用 switch

let value = 1


switch value {
case let val where val > 0:
print("\(val) is greater than zero")
case let val where val == 0:
print("\(val) is zero")
case let val where val < 0:
print("\(val) is less than zero")
default:
fatalError()
}

# 4使用带 where 子句的 switch 和对 _的赋值

let value = 1


switch value {
case _ where value > 0:
print("greater than zero")
case _ where value == 0:
print("zero")
case _ where value < 0:
print("less than zero")
default:
fatalError()
}

# 5与 RangeExpression协议的 ~=(_:_:)操作员使用交换机

let value = 1


switch true {
case 1... ~= value:
print("greater than zero")
case ..<0 ~= value:
print("less than zero")
default:
print("zero")
}

# 6与 Equatable协议的 ~=(_:_:)操作员使用交换机

let value = 1


switch true {
case value > 0:
print("greater than zero")
case value < 0:
print("less than zero")
case 0 ~= value:
print("zero")
default:
fatalError()
}

# 7与 PartialRangeFromPartialRangeUpToRangeExpressioncontains(_:)方法一起使用开关

let value = 1


switch true {
case (1...).contains(value):
print("greater than zero")
case (..<0).contains(value):
print("less than zero")
default:
print("zero")
}

很高兴 Swift 4解决了这个问题:

作为一个解决方案,我做到了:

switch translation.x  {
case  0..<200:
print(translation.x, slideLimit)
case  -200..<0:
print(translation.x, slideLimit)
default:
break
}

有用,但不理想

斯威夫特5号现在很干净

switch array.count {
case 3..<.max:
print("Array is greater than or equal to 3")
case .min..<3:
print("Array is less than 3")
default:
break
}

我能想到的最干净的解决办法:

switch someVar {
case ..<0:
// do something
case 0:
// do something else
default:
// etc
}