Swift 在if-case中case是如何工作的
一个老C程序员可能需要一些Swift的帮助 我对if-case语法不太了解。例如:Swift 在if-case中case是如何工作的,swift,Swift,一个老C程序员可能需要一些Swift的帮助 我对if-case语法不太了解。例如: if case 20...30 = age { print ("in range.") } 案例20…30=age似乎是if语句的条件测试。因此,一开始我很困惑地看到使用赋值运算符('=')而不是比较运算符('=') 好的,我想,这可能意味着case语句实际上是一个返回布尔值的函数调用。然后返回的值将满足if语句中的比较测试 作为一个实验,我尝试将case语句当作常规条件测试,并在其周围加上括号。如果(x
if case 20...30 = age {
print ("in range.")
}
案例20…30=age
似乎是if
语句的条件测试。因此,一开始我很困惑地看到使用赋值运算符('=')而不是比较运算符('=')
好的,我想,这可能意味着case
语句实际上是一个返回布尔值的函数调用。然后返回的值将满足if
语句中的比较测试
作为一个实验,我尝试将case
语句当作常规条件测试,并在其周围加上括号。如果(x==5)或if(true)
,Swift将乐意接受。但是如果(案例20…30=年龄)
生成错误。因此,case
语句的行为似乎与函数不同
我只是想知道这里发生了什么。如果您有任何见解,我们将不胜感激。运算符是if case
,因此您不能用括号括起来。语法和行为基于Swiftswitch
语句中的case
语句(请查看是否需要详细信息)。在案例
语句中,20…30
是一个区间,用作模式,通过对区间使用包含
进行操作。等号确实令人困惑,但这是他们第一次尝试使用语法来表示大小写
语句应该与之比较的内容(即开关
语句中开关
关键字后面的标记)
因此,如果您理解这一点:
switch age {
case 20...30:
// do stuff
default:break
}
。。。然后你就明白了它是如何直接变形成这样的:
if case 20...30 = age {
// do stuff
}
@matt很好地解释了代码的功能。我来这里是想提出一个更好的选择
您可以使用操作员检查范围。它是一个常规运算符/函数,只返回一个Bool
,没有特殊的语言魔力
if 20...30 ~= age {
print ("in range.")
}
关于这些Swift操作员的另一个注意事项。我们必须记住,Swift有一个非常高级和抽象的编译器,所以关键字只是关键字,它们的行为取决于它们的用法。
与C(以及C++相关的其他与JavaScript相关的语言)不同,在这里,<>代码>如果被简单地用来测试布尔值(或者可以转换为一个的值),在SWIFT中,如果语句的概念要更广泛。strong>我通常认为它通过使用各种技术(包括布尔测试)来限制对范围的访问。
您可以将if
、guard
、while
、和repeat
-while
看作更通用的控制流语句,具有更高级的行为。当然,他们仍然可以测试布尔值,但他们也可以测试其他条件。在您的场景中,测试的条件是某个变量是否与定义的模式匹配(年龄是否与模式匹配)
您还可以测试变量是否成功设置为非nil
值(if-let
)。let
操作的结果永远不会返回布尔值,但由于它发生在if
语句中,因此Swift运行时知道它是控制流的一部分。还请注意,这稍微改变了let
的行为,因为if
块中的任何代码现在都看到了新的非nil
值,并确保它不是nil
这些行为也可以与逗号组合,如下所示:
if !skipAgeTest, // `if` tests a Boolean
let age = Double(ageString), // `if` tests optional assignment
case 20...30 = age // `if` tests pattern matching
{
// `age` variable exists and is not `nil` and is between `20` and `30`, inclusive
}
因此,if let
或if case
作为独立运算符的概念是。。。没有用正确的方式思考它
正如我所说,此语法在其他控制流中也有效:
while !skipAgeTest,
let age = Double(ageString),
case 20...30 = age {
// `age` is validated
// Probably also change `ageString` while we're in here
}
guard !skipAgeTest,
let age = Double(ageString),
case 20...30 = age
else {
// `age` is invalid, and not available in this block
}
// `age` is valid
尽管已经给出了正确答案,但仍有一个选择:
20…30
是一个ClosedRange,它有一个内置的方法,可读性更强,可以为您工作:包含
if (20...30).contains(age) {
print ("in range.")
}
射程控制
使用操作符,如@Alexander所述
if (1...10).contains(n) {
print("pass")
}
switch n {
case 1...10: print("pass")
default: print("bug")
}
if case 1...10 = n {
print("pass")
}
if 1...10 ~= n {
print("pass")
}
您甚至可以执行以下字符范围的操作:
if "a"..."z" ~= "a" {
print("pass")
}
超载~=
我做了一些重载,这样您不仅可以检查范围,还可以检查数组和集合
func ~=<T: Equatable> (pattern: [T], value: T) -> Bool { return pattern.contains(value) }
func ~=<T: Equatable> (pattern: Set<T>, value: T) -> Bool { return pattern.contains(value) }
func ~=<T: Equatable> (pattern: Set<T>, value: Set<T>) -> Bool { return pattern.union(value).count < pattern.count + value.count }
多元组
但是,在使用元组时,如果大小写为
if case (1...10, 1...10) = (number1, number1) {
print("0")
}
你甚至可以做。
语法糖
if case (1...10, _) = (number1, number1) {
print("0")
}
可选项
相关:,。如果你觉得你的问题已经得到回答,请投票并接受并回答。为什么如果20…30 ~=age
“比如果case 20…30 ~=age
”更不特别的语言魔力(不管这意味着什么)或者“比更好”?如果case
语法混乱(否则这个问题就不存在了)。2) ~=
是一个常规函数,任何不知道它的人都可以命令单击它并查看其实现,就像其他任何外部函数一样。如果我们想要更清晰的替代方案,我还建议If(20…30).contains(age){…}
将模式匹配操作符视为标题实际上并没有确切说明它的作用。如果你想“没有特殊的语言魔法”,为什么要使用Swift?@Alexander它在Xcode 8.x中使用过,但当他们为Xcode 9.x重写编辑器时,他们没有将该功能重新添加进去。我于2017年7月11日提交了一份雷达报告,但未收到任何回复。因为它没有关闭,我怀疑他们正在重新实施它。这很有帮助,谢谢。我可以看到if case
是如何从switch case
演变而来的,但我很高兴知道其他人也发现在语法中使用等号是令人困惑的。我相信语法在未来会发生变化。当双方可以互换时,这更令人困惑-就像if myBool==true{…
是等效的
if case (1...10, _) = (number1, number1) {
print("0")
}
if case .some = Optional(number) {
print("pass")
}
if case .some(let x) = Optional(number) {
print(x)
}
if case let x? = Optional(number) {
print(x)
}