Swift3.0学习笔记-Control Flow

    https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID120

        跟C/Java语法一样,  Swift提供了多种流程控制的语法, 包括while循环、if逻辑判断、break跳出循环和continue回到判断条件继续循环等。

       Swift还支持for-in循环语法, 从而遍历数组、字典、区间、字符串和其它序列变得很方便。

       Swift的switch/case关键字做的很强大, 不需要break关键字!!!跟Java/C/OC的用法完全不一样。  case后面可以是个语句、甚至还能用where(感觉像SQL有没有?  在Java/C/OC里是没有where关键字的!), 而Java/C的case只能是数字。


        前面4篇已经提到了Swift支持for-in循环, 这里再详细描述一下for-in的所有用法:

第1种用法: 在in后面返值数字区间...或者..<运算符, 表示循环多少次。

    for index in 1...5 {
        print("\(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
 看过前面4篇笔记后, 这2行代码大概能猜出来, index的取值范围就是1...5即[1,5],   因为是整型每次循环自增1, 所以index值按先后顺序是1/2/3/4/5。 如果换成for index in 1..<5会怎样?    index值会是1/2/3/4,即循环4次。

       有些情况下我们只需要循环N次,  循环中不关心当前是第几次,  即不需要变量index。 Swift语言使用下划线作为for-in语句的占位符(PS:感觉是抄了SQL语法, 当然Java/C/OC是不支持该特性的)

    let base = 3
    let power = 10
    var answer = 1
    for _ in 1...power {
        answer *= base
    }
    print("\(base) to the power of \(power) is \(answer)")
    // 输出"3 to the power of 10 is 59049" 
    // 上面示例使用_替换了index,是为了说明循环10次却不用当前次数的情况,结果等于3^10。 
    // 我觉得可以忽略这个写法,只使用带参数index的语法。 因为大多数情况下还是需要用当前次数的,多个参数
又能怎样? 是吧! 

第2种用法: 遍历Array、Set或者Dictionary, 跟Java遍历ArrayList语法一样。

    let names = ["Anna", "Alex", "Brian", "Jack"]  //names是[String]数组,在Swifit创建数组是用[],而Java是
   用{}
  for name in names {
        print("Hello, \(name)!")
    }
    // Hello, Anna!
    // Hello, Alex!
    // Hello, Brian!
    // Hello, Jack!

       说明:  上面这个语法跟Java相同, 相信很好理解。


      Swift还能通过上述方式遍历Dictionary, 想想Java的HashMap能是否for-in方法遍历吗? 答:可以的,  for循环里遍历HashMap的key(详看我的另一篇博客”HashMap源码分析”)。语法如下:

    let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] //numberOfLegs是Dictionary<String,Int>类型,
    注意key-value之间用冒号分隔, 键值对之间以逗号分隔。
   for (animalName, legCount) in numberOfLegs {   //animalName是String类型变量,legCount是Int型变量
        print("\(animalName)s have \(legCount) legs")
    }
    // ants have 6 legs
    // spiders have 8 legs
    // cats have 4 legs


 While循环, Swift参考了C语言的while和do-while语法,  支持while和repeat-while语法。 如果你懂C或Object-C, 就很好理解了。 Swift语言的while对应C语言的while, Swift语言的repeat-while对应C语言的do-while。

while和repeat-while的唯一区别是while要先判断再执行循环, repeat-while是先执行循环再判断。 所以判断条件为false时, while不会执行循环体, 但repeat-while会执行一次循环体。

var square = 0
var diceRoll = 0
while square < finalSquare {
    print("first execute")
}
无输出!

repeat {
   print("first execute")
} while square < finalSquare
输出 "first execute"

这就是while和repeat-while的唯一区别!


If

   Swift跟C/OC/Java的If关键字功能、用法是一致的,  就是判断if后面值为true or false来执行函数体, true执行if函数体,  false执行else函数体。 Swift还支持if/else if/else, 语法也跟C/Java一模一样。

temperatureInFahrenheit = 40
if temperatureInFahrenheit <= 32 {
    print("true execute")
} else {
    print("false execute")
}
<code class="code-voice"><span class="c">// 因为42大于32,temperatureInFahrenheit <= 32为false, 所以执行else函数体,输出"false execute" 

</span></code><code class="code-voice"><span class="c"></span></code><pre name="code" class="java">if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
} else {
    print("It's not that cold. Wear a t-shirt.")
}
因为temperatureInFahrenheit不满足前2个if判断,执行了else分之语句,输出"It's not that cold. Wear a t-shirt."

 

Switch

         相对于C/Java/OC语言来说, Swift对switch-case做了很多改进,case后面可以跟一条语句且支持Character类型。  下面仔细说明Swift对switch-case都做了哪些改造。

switch some value to consider {
case value 1:
    respond to value 1
case value 2,
     value 3:
    respond to value 2 or 3
default:
    otherwise, do something else
}
<pre name="code" class="java">let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
default:
    print("Not the letter A")
}

 
//这是基本用法, 跟Java/C/OC是类似。区别是Swift没执行<span style="color:#ff0000;"><strong>break</strong></span>,多个值时如<span style="font-family: Arial, Helvetica, sans-serif;">2/3中间用<strong><span style="color:#ff0000;">逗号</span></strong>分开作为一个case; 而Java是分成2个case,Java写法如下</span>
swith some value to consider {
case value 1:
     respond to value 1
     break;
case value 2:
case value 3:
     response to value 2 or 3
     break;
default:
}

 Swift的case后面还可以跟Character类型(Java/C仅支持整型), 例如

let someCharacter: Character = "z"       //注意:Swift里的字符型Character使用双引号, 而Java/C使用单引号!
switch someCharacter {
case "a":
    print("The first letter of the alphabet")
case "z":
    print("The last letter of the alphabet")
default:
    print("Some other character")
}
// 输出"The last letter of the alphabe


   前面提到了Swift的case后面可以跟一条语句, 那么范围区间更是不在话下了。

let approximateCount = 62
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch approximateCount {
case 0:
    naturalCount = "no"
case 1..<5:
    naturalCount = "a few"
case 5..<12:
    naturalCount = "several"
case 12..<100:
    naturalCount = "dozens of"
case 100..<1000:
    naturalCount = "hundreds of"
default:
    naturalCount = "many"
}
<pre name="code" class="java">print("There are \(naturalCount) \(countedThings).")
// 因为62符合case 12..<100条件,所以输出"There are dozens of moons orbiting Saturn."

 switch-case语法还支持键值对, 也是用下划线做占位符。 

let somePoint = (1, 1)    //理解为(x, y)格式
switch somePoint {
case (0, 0):
    print("(0, 0) is at the origin")
case (_, 0):
    print("(\(somePoint.0), 0) is on the x-axis")   //somePoint.0得到x
case (0, _):
    print("(0, \(somePoint.1)) is on the y-axis")   //somePoint.1得到y
case (-2...2, -2...2):
    print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
<pre name="code" class="java">// 输出"(1, 1) is inside the box"

 

如果要判断(x, y)其中一个值等于某值, 然后取另一个值该如何做? Swift也做了支持, 语法如下

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):     //含义是当anotherPoint.1等于0时, 将anotherPoint.0赋值给x,并执行case下的语句
    print("on the x-axis with an x value of \(x)")
case (0, let y):    //含义是当anotherPoint.0等于0时, 将anotherPoint.1赋值给x,并执行case下的语句
    print("on the y-axis with a y value of \(y)")
case let (x, y):    //含义是任意数值将anotherPoint.0赋值给x,anotherPoint.1赋值给y。注意let放在圆括号的左边!在本switch中相当于default, 如果前面的case都是false, 那么就会执行到里面,例如anotherPoint是(3, 3),那么会输出"somewhere else at (3, 3)
    print("somewhere else at (\(x), \(y))")
}
// 因为(2, 0)符合(let x, 0)的条件, 所以输出"on the x-axis with an x value of 2"

Switch还对switch-case的let做了个高级功能, 添加where关键字(可以理解为当, 即后续语句条件满足时)。 解决有些时候需要判断2个值的关系时的逻辑,懂得SQL语言的话就很好理解, 语法如下:

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:        //当yetAnotherPoint.0等于yetAnotherPoint.1时执行
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:   //当yetAnotherPoint.0等于yetAnotherPoint.1负数时执行
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):  //相当于default语句, 如果前面case都是false则会执行。
    print("(\(x), \(y)) is just some arbitrary point")
}
//1和-1符合x==-y的条件, 所以会输出"1, -1 is on the line x == -y"

前面提到了case后面可以跟多个值,中间用逗号分隔; 这个值还可以是键值对! 比如

let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance): //2个键值对,sitllAnotherPoint.0或.1等于0时为真
    print("On an axis, \(distance) from the origin")
case (let distance, 1)  //stillAnotherPoint.1等于1时为真
    print("when y equals 1, \(distance) test 1")
case (2, let distance)  //stillAnotherPoint.0等于2时为真
    print("when x equals 2, \(distance) test 2")
default:
    print("Not on an axis")
}
因为第1个case为真, 所以输出:"On an axis, 9 from the origin"


练习:

var sValue = "a"
switch sValue {
case "a", "b", "c":
    print("a first")   //不需要break关键字
case "a":
    print("a0")
    print("a1")
case "b", "a":
    print("bbbb")
default:
    print("default")
}
输出: a first

说明: 跟Java/C不同的是,Swift的每个case都是个代码块, 并会在最后跳出switch;必须有default, 否则XCode提示错误;



Swift的break、continue跟其它语言完全一样, 可以不废话了。


Fallthrough关键字, 作用类似于try/catch/finally里的finally或者C语言里的goto, 即肯定会跳转到最后执行!而且仅用在switch/case语句里。语法如下:

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语句里, 有点像C语言的goto
default:
    description += " an integer."
}
print(description)
// 输出"The number 5 is a prime number, and also an integer."


Lable语句, Swift提供了类似于C语言goto的语法, 用在while循环里, 实现中断循环并跳转到前面的while判断继续执行的功能。 

label name: while condition {
    statements
}
上面是语法格式


gameLoop: while square != finalSquare {
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    switch square + diceRoll {
    case finalSquare:
        // 跟Java一样跳出while循环
        break gameLoop
    case let newSquare where newSquare > finalSquare:
        // 跟Java类似,跳转到while语句
        continue gameLoop
    default:
        // this is a valid move, so find out its effect
        square += diceRoll
        square += board[square]
    }
}


在Java函数体前几句经常是判断某些参数是否为空,为空时return即退出函数体。 Swift对这种情况创造了新的语法进行支持, 提供guard关键字,功能类似于if, 区别是guard后面总跟着是else语句。 当然你也可以不用guard关键字, 使用if关键字完全可以实现判空的功能。

func greet(person: [String: String]) {   //Java里使用func声明函数, greet是函数名称
    guard let name = person["name"] else {  //该语句的意思是将person["name"]赋值给name, 当name为nil时执行else语句,不是nil时跳过继续向下执行, 即做了Java的参数判空逻辑
        return
    }
    
    ...
}
 


小结: 

1、switch/case默认必须带default分支,否则编译报错; 只有一种情况除外, 即switch的是枚举!

2、guard关键字用于函数参数逻辑判空(类似于Java);

3、continue/break实现类似于c语言的goto功能;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值