变量参数,正如上面所述,仅仅能在函数体内被更改。如果你想要一个函数可以修改参数的值,并且想要在这些修改在函数调用结束后仍然存在,那么就应该把这个参数定义为输入输出参数(In-Out Parameters)。
定义一个输入输出参数时,在参数定义前加 inout
关键字。一个输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。想获取更多的关于输入输出参数的细节和相关的编译器优化,请查看输入输出参数一节。
你只能传递变量给输入输出参数。你不能传入常量或者字面量(literal value),因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数名前加&
符,表示这个值可以被函数修改。
Swift 中的switch
不会从上一个 case 分支落入到下一个 case 分支中。相反,只要第一个匹配到的 case 分支完成了它需要执行的语句,整个switch
代码块完成了它的执行。相比之下,C 语言要求你显式地插入break
语句到每个switch
分支的末尾来阻止自动落入到下一个 case 分支中。Swift 的这种避免默认落入到下一个分支中的特性意味着它的switch
功能要比 C 语言的更加清晰和可预测,可以避免无意识地执行多个 case 分支从而引发的错误。
如果你确实需要 C 风格的贯穿的特性,你可以在每个需要该特性的 case 分支中使用fallthrough
关键字。下面的例子使用fallthrough
来创建一个数字的描述语句。
let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
fallthrough
default:
description += " an integer."
}
print(description)
// 输出 "The number 5 is a prime number, and also an integer."
这个例子定义了一个String
类型的变量description
并且给它设置了一个初始值。函数使用switch
逻辑来判断integerToDescribe
变量的值。当integerToDescribe
的值属于列表中的质数之一时,该函数添加一段文字在description
后,来表明这个是数字是一个质数。然后它使用fallthrough
关键字来“贯穿”到default
分支中。default
分支添加一段额外的文字在description
的最后,至此switch
代码块执行完了。
如果integerToDescribe
的值不属于列表中的任何质数,那么它不会匹配到第一个switch
分支。而这里没有其他特别的分支情况,所以integerToDescribe
匹配到包含所有的default
分支中。
当switch
代码块执行完后,使用print(_:separator:terminator:)
函数打印该数字的描述。在这个例子中,数字5
被准确的识别为了一个质数。
注意:
fallthrough
关键字不会检查它下一个将会落入执行的 case 中的匹配条件。fallthrough
简单地使代码执行继续连接到下一个 case 中的执行代码,这和 C 语言标准中的switch
语句特性是一样的。
在 Swift 中,你可以在循环体和switch
代码块中嵌套循环体和switch
代码块来创造复杂的控制流结构。然而,循环体和switch
代码块两者都可以使用break
语句来提前结束整个方法体。因此,显式地指明break
语句想要终止的是哪个循环体或者switch
代码块,会很有用。类似地,如果你有许多嵌套的循环体,显式指明continue
语句想要影响哪一个循环体也会非常有用。
为了实现这个目的,你可以使用标签来标记一个循环体或者switch
代码块,当使用break
或者continue
时,带上这个标签,可以控制该标签代表对象的中断或者执行。
产生一个带标签的语句是通过在该语句的关键词的同一行前面放置一个标签,并且该标签后面还需带着一个冒号。下面是一个while
循环体的语法,同样的规则适用于所有的循环体和switch
代码块。
label name: while condition {
statements
}
gameLoop: while square != finalSquare { if ++diceRoll == 7 { diceRoll = 1 } switch square + diceRoll { case finalSquare: // 到达最后一个方块,游戏结束 break gameLoop case let newSquare where newSquare > finalSquare: // 超出最后一个方块,再掷一次骰子 continue gameLoop default: // 本次移动有效 square += diceRoll square += board[square] } } print("Game over!")