Answers:
这是一种方法。假设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")
}
可以简化一下:
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)")
}
default: fatalError()
及早发现可能的逻辑错误。
assertionFailure
似乎是一个更安全的选择,尤其是在团队合作中。
使用Swift 5,您可以选择以下开关之一来替换if语句。
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()
}
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()
}
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()
}
_
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()
}
RangeExpression
协议的~=(_:_:)
运算符一起使用switchlet value = 1
switch true {
case 1... ~= value:
print("greater than zero")
case ..<0 ~= value:
print("less than zero")
default:
print("zero")
}
Equatable
协议的~=(_:_:)
运算符一起使用switchlet 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()
}
PartialRangeFrom
,PartialRangeUpTo
和RangeExpression
的contains(_:)
方法let value = 1
switch true {
case (1...).contains(value):
print("greater than zero")
case (..<0).contains(value):
print("less than zero")
default:
print("zero")
}
0.1
引发致命错误,因为1...
仅涵盖1以后的数字。因此,此解决方案仅在value
为时才有效,Int
但这很危险,因为如果变量类型更改,功能中断就不会出现任何编译器错误。
该switch
声明,引擎盖下,采用~=
运营商。所以这:
let x = 2
switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}
糖到此:
if 1 ~= x { print(1) }
else if 2 ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else { }
如果您看一下标准库参考,它可以准确地告诉您什么~=
是重载:包括范围匹配和等于等值的东西。(不包括枚举大小写匹配,这是一种语言功能,而不是标准库中的函数)
您会发现它与左侧的直线布尔值不匹配。对于这种比较,您需要添加一个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: ...
}
但是现在您必须定义new isNegative
和isPositive
函数。除非您重载更多运算符...
您可以将普通的infix运算符重载为咖喱前缀或postfix运算符。这是一个例子:
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语句模式
switch x {
case negative:
case 0:
case positive:
}
要么
switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}
似乎很普遍,值得考虑。
这是范围的样子
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
}
X_MAX
已被替换为.greatestFiniteMagnitude
,即Double.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
等等。因此通常,您可以这样做,case 0..< .greatestFiniteMagnitude
因为的类型someVar
是已知的
var timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
为什么 <=
无法识别操作员?如果我在没有平等的情况下编写它,它将起作用。谢谢
someVar
是an Int
,因此我必须做Double(
someVar)`才能使它工作...