四、控制流 control flow

1 Switch控制语句

1.1 Switch概述

1.1.1 No Implicit Fallthrough - 没有隐性掉入

  相比C和objective-c中的switch语 句,Swift中(如果忘了写break)的switch不会默认的掉落到每个case的下面进入另一 个case。相反,switch语句当第一个遇到的case完成时就完成了它整个的执行,不需要写break。因此比起C语言,swift的switch 更加安全和简单,避免了执行多个case的错误。

  每一个switch语句都必须exhaustive(详细),并且每一个所考虑类选可能的值都必须匹配switch中的一个case。如果不能对应到switch中的所有case的值,可以定义个默认的选取器来解决。选取器用default关键字来表示,必须出现在最后。

  每个case的主干包括只少一个可执行的语句。下面这样写是无效的,因为第一个case是空的: 

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a":
case "A":
    println("The letter A")
default:
    println("Not the letter A")
}
// this will report a compile-time error

1.1.2 如果有多个匹配对象的,可以用逗号隔开,像下面这样写成多行:

switch some value to consider {
  case value 1,
  value 2:
      statements
}

1.1.3 为特别的switch case选择掉落行为,可以使用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."
}
println(description)
// prints "The number 5 is a prime number, and also an integer."

  例子中声明了一个名为description的String型变量并分派一个初始值。然后函数用switch匹配integerToDescribe的 值。如果integerToDescribe的值符合素数列表中的一项,最后的description会增加一段字符,注意数字都是素数。然后用 fallthrough关键字让代码“掉到”default里。default的代码中再额外的给字符串添加些描述,最后switch结束。

  如果integerToDescribe不跟素数表中任何一项匹配,那根本就不会匹配switch的第一个case。这里面没有其他的case,因此integerToDescribe直接进入default容器。

  NOTE:
  fallthrough关键字不检查case里的条件,会直接掉入下一个case。fallthrough简单的让代码执行到下一个case(或default)的代码块中,和标准C语言的特性一样。

 

1.2 Range Matching - 范围匹配

switch中case的值可以检查他们内在的范围。这个例子使用数字范围可以提供任意大小数字的自然语言计数。

let count = 3_000_000_000_000
let countedThings = "stars in the Milky Way"
var naturalCount: String
switch count {
case 0:
    naturalCount = "no"
case 1...3:
    naturalCount = "a few"
case 4...9:
    naturalCount = "several"
case 10...99:
    naturalCount = "tens of"
case 100...999:
    naturalCount = "hundreds of"
case 1000...999_999:
    naturalCount = "thousands of"
default:
    naturalCount = "millions and millions of"
}
println("There are \(naturalCount) \(countedThings).")
// prints "There are millions and millions of stars in the Milky Way."

 

1.3 Switch语句中Turple的使用

你可以使用元组在相同的switch语句中测试多个值。每一个元组中的元素都可以试着和范围中不同的值进行匹配。另外,用下划线(_)标示符来匹配任意可能的值。

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    println("(0, 0) is at the origin")
case (_, 0)://使用下划线(underscore)代表任何可能的值
    println("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    println("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
    println("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    println("(\(somePoint.0), \(somePoint.1)) is outside of the box")

//prints "(1, 1) is inside the box"

Switch语句决定了点是否在原点(0,0)上,在红色的x轴上,在橙色的y轴上,在蓝色4X4的矩形为中心的原点内,或者在矩形外。

  与C语言不同,Swift允许多个switch的case考虑相同的值。实际上点(0,0)能匹配例子中所有的四个case。然而,如果多个匹配出现,第一个匹配成功的case将被使用。点(0,0)能首先匹配case(0,0),所以其他所有的case将被忽略。

 

1.3. Switch中值绑定 Value Bindings

  一个switch的case能绑定用于匹配临时常量或变量值,在case的分支代码里使用。这就是value binding(值绑定),因为这些值在case的代码体中是临时常量或变量的“边界”。

  下面的例子有一个点(x,y),用元组型(Int,Int)来表示,在图种展示出来如下:

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
  println("on the x-axis with an x value of \(x)")
case (0, let y):
  println("on the y-axis with a y value of \(y)")
case let (x, y):
  println("somewhere else at (\(x), \(y))")
}

  三个switch的case都声明了占位常量x和y,暂时从anotherPoint占用一个或两个元组值。

  一旦临时常量被声明,他们将在case的代码块中使用。这里他们将作为简写在println函数中打印出来。  

  注意switch语句没有default的case。最后一个case,case let (x, y),声明了包含两个占位常量可以匹配任何值的元组。作为结果,它匹配任何可能的值,不需要default语句switch就足够完美了。

 

1.4 Switch中Where的使用

switch的case能使用where子句来进一步判断条件。 下面的例子将点(x,y)在下图种分类:

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
  println("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
  println("(\(x), \(y)) is on the line x == -y")
case let (x, y):
  println("(\(x), \(y)) is just some arbitrary point")
}
// prints "(1, -1) is on the line x == -y"

1.5 给循环(Loop)和Switch添加标签(Lable)

当多个Loop或Switch嵌套时,可以给某个Loop或Switch绑定一个标签,这样可以使用break和continue对特定的Loop和Switch进行操作,

写法:

 

1.6 switch与循环中的控制语句

continue 结束本次循环

break 终止整个循环

fallthrough 进入下一个case

default 没有任何case匹配时,进入default

 

2. for in 语句

2.1 使用for-in来遍历集合中的项目,比如数组的范围,排列中的项或者字符串中的字符。

for index in 1...5 {
     println("\(index) times 5 is \(index * 5)")
 }
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
 // 4 times 5 is 20
// 5 times 5 is 25 

2.2 如果不需要范围的值,可以用下划线替代变量名来忽略这些值:

let base = 3
   let power = 10
   var answer = 1
   for _ in 1...power {
       answer *= base
 }
 println("\(base) to the power of \(power) is \(answer)")
 // prints "3 to the power of 10 is 59049"

2.3 迭代字典

Dictionary中的项的迭代顺序可能跟它们插入时的顺序不一样。因为Dictionary中的内容本质上是无序的,所以迭代它们不能保证检索时的顺序。

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
  println("\(animalName)s have \(legCount) legs")
}
// spiders have 8 legs
// ants have 6 legs
// cats have 4 legs

 

posted @ 2015-01-06 16:57  action爱生活  阅读(501)  评论(0编辑  收藏  举报