Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在if-case中case是如何工作的_Swift - Fatal编程技术网

Swift 在if-case中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

一个老C程序员可能需要一些Swift的帮助

我对if-case语法不太了解。例如:

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
,因此您不能用括号括起来。语法和行为基于Swift
switch
语句中的
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)
 }