小于或大于Swift switch语句

Pie*_*ter 130 switch-statement swift

我熟悉switchSwift中的语句,但想知道如何用以下代码替换这段代码switch:

if someVar < 0 {
    // do something
} else if someVar == 0 {
    // do something else
} else if someVar > 0 {
    // etc
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*ger 222

这是一种方法.假设someVar是一个Int或另一个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")
}
Run Code Online (Sandbox Code Playgroud)

这可以简化一下:

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")
}
Run Code Online (Sandbox Code Playgroud)

您还可以where使用范围匹配完全避免关键字:

switch someVar {
case Int.min..<0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
default:
    print("someVar is \(someVar)")
}
Run Code Online (Sandbox Code Playgroud)

  • 我建议`default:fatalError()`尽早检测可能的逻辑错误. (9认同)
  • @MartinR `assertionFailure` 似乎是一个更安全的选择,尤其是在团队中工作时。 (3认同)

Ima*_*tit 90

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


#1使用带PartialRangeFrom和的开关PartialRangeUpTo

let value = 1

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

#2使用带ClosedRange和的开关Range

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()
}
Run Code Online (Sandbox Code Playgroud)

#3将switch与where子句一起使用

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()
}
Run Code Online (Sandbox Code Playgroud)

#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()
}
Run Code Online (Sandbox Code Playgroud)

#5使用带RangeExpression协议~=(_:_:)运算符的开关

let value = 1

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

#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()
}
Run Code Online (Sandbox Code Playgroud)

#7使用交换机PartialRangeFrom,PartialRangeUpToRangeExpressioncontains(_:)方法

let value = 1

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

  • 概述不错,但有缺陷,因为未说明0到1之间的数字。“ 0.1”会引发致命错误,因为“ 1 ...”仅覆盖1以后的数字。因此,此解决方案仅在“值”为“ Int”的情况下有效,但这很危险,因为如果变量类型更改,则功能中断而无需任何编译器错误。 (2认同)

ois*_*sdk 19

switch声明,引擎盖下,采用~=运营商.所以这:

let x = 2

switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}
Run Code Online (Sandbox Code Playgroud)

Desugars to this:

if 1          ~= x { print(1) }
else if 2     ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else {  }
Run Code Online (Sandbox Code Playgroud)

如果查看标准库引用,它可以准确地告诉您~=要重载的内容:包括范围匹配,以及等同于等同的东西.(不包括枚举大小写匹配,这是一种语言特性,而不是std lib中的函数)

您会看到它与左侧的直布尔值不匹配.对于那些比较,您需要添加where语句.

除非......你~=自己超载了操作员.(通常建议这样做)一种可能性是这样的:

func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool {
  return lhs(rhs)
}
Run Code Online (Sandbox Code Playgroud)

因此匹配一个函数,该函数在左侧返回一个布尔值,在右侧返回其参数.这是你可以用它来做的事情:

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

switch 2 {
case isEven: print("Even!")
default:     print("Odd!")
}
Run Code Online (Sandbox Code Playgroud)

对于您的情况,您可能有一个如下所示的语句:

switch someVar {
case isNegative: ...
case 0: ...
case isPositive: ...
}
Run Code Online (Sandbox Code Playgroud)

但现在你必须定义新的isNegativeisPositive功能.除非你超载一些运营商......

您可以将正常的中缀运算符重载为curried前缀或后缀运算符.这是一个例子:

postfix operator < {}

postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool {
  return lhs < rhs
}
Run Code Online (Sandbox Code Playgroud)

这将是这样的:

let isGreaterThanFive = 5<

isGreaterThanFive(6) // true
isGreaterThanFive(5) // false
Run Code Online (Sandbox Code Playgroud)

将它与早期的函数结合使用,你的switch语句可能如下所示:

switch someVar {
case 0< : print("Bigger than 0")
case 0  : print("0")
default : print("Less than 0")
}
Run Code Online (Sandbox Code Playgroud)

现在,你可能不应该在实践中使用这种东西:它有点狡猾.你(可能)更好地坚持这个where说法.也就是说,switch语句模式

switch x {
case negative:
case 0:
case positive:
}
Run Code Online (Sandbox Code Playgroud)

要么

switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}
Run Code Online (Sandbox Code Playgroud)

似乎很常见,值得考虑.


rin*_*aro 14

您可以:

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


Jer*_*ews 8

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

作为 3 中的解决方法,我做了:

switch translation.x  {
case  0..<200:
    print(translation.x, slideLimit)
case  -200..<0:
    print(translation.x, slideLimit)
default:
    break
}
Run Code Online (Sandbox Code Playgroud)

有效但不理想


sim*_*ons 6

既然已经有人贴出case let x where x < 0:这里是哪里的替代someVar是一个Int.

switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}
Run Code Online (Sandbox Code Playgroud)

这里是其中的另类someVarDouble:

case -(Double.infinity)...0: // do something
// etc
Run Code Online (Sandbox Code Playgroud)


GOr*_*o58 6

这是范围的样子

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"
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

Swift 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
}
Run Code Online (Sandbox Code Playgroud)