WWDC14 Session 402 學習筆記 (中)

前言

上回書說道,我們在一個 <Stirng, Int> 的字典裡面查找信息。但明顯遇到了一個問題:Int是一個Value不是引用,也就是不能傳回來NSNull之類的東西了。若像NSString的Range一樣返回NSNotFound(-1)的話,也不對。畢竟-1以及-2147483648~2147483647都是我們可能要的數據。所以返回數字不成立。那該怎麼辦?

? !

對你沒看錯,我沒有打錯,標題就是 ? !,這不是三元運算符,也不是not,而是Swift的新用法。據楷雯說,這是從Ruby抄過來的特性。

?

? 表示的是:Optional。寫法如下:

1
var possibleValue: Int? = animalLegs["chihuahua"]

這樣得到的是一個wrapper(注意wrapper的w不發音,讀作[ˈræpə]),他可以用nil判斷了。如下:

1
2
3
4
5
6
if possibleValue {
  println("Nyan")
}
else {
  println("> <")
}

不過這個 類似NSNumber 的東西,不能通過intValue之類的途徑獲得裡面的內容,這時 !就出場了。

!

!的作用就是突破Optional,拿到內部值

1
2
3
4
5
6
7
if possibleValue {
  let value = possibleValue!
  println("Chihuahua has \(value) legs")
}
else {
  println("> <")
}

不過這裡,有個簡練的寫法,更漂亮優雅。

1
2
3
4
5
6
7
8
if let value = possibleValue
{
  println("Chihuahua has \(value) legs")
}
else
{
  println("> <")
}

Control Flow

我上高中的時候,選修課老師和我吹水時提到: 無論多麼精緻的程序,多麼炫酷的算法,全都是由順序,循環,分支組成的。

順序循環前面都介紹過了,這裡來把分支介紹了。

單路分支,

1
2
3
4
if blablabla {
}
else{
}

注意:這裡里的大括號不可以省略。

多路分支

1
2
3
4
5
6
7
8
9
switch num
{
case 1:

case 2:

default:

}

注意:不再需要寫break,且default必須有!且必須所有條件都要覆蓋到,一般情況下都會有default,但是若在enum中使用,就可以用case搞定了。

對於case來說,不僅可以寫 case 1, case 2, 還可以寫 case 1, 2, 3, 4, 甚至 case, 1, 2, 3, 4, 7..10。

Function

函數是編程語言必不可少的元素,Swift的函數聲明相對於OC也有很多靈活的地方。

先從最基礎的函數樣式開始說起:

1
2
3
4
5
func printHelloWorld(){
  println("Hello World")
}

printHelloWorld()

傳參數:

1
2
3
4
5
6
7
8
func printMessage(message:String, repeat: Int){
  for i in 1...repeat   {
      println(message)
  }
}

printMessage(message: "Hello World", repeat: 2)
printMessage("Hello World", 2)//在沒有默認參數的情況下可以這麼寫

與OC不同,這裡可以預置默認參數

1
2
3
4
5
6
7
8
func printMessage(message:String = "Hello World", repeat: Int = 1){
    for i in 1...repeat     {
        println(message)
    }
}

printMessage()
printMessage(repeat: 2)

返回值:

1
2
3
4
5
6
func plus(a: Int, b: Int)->Int
{
  return a + b
}

println(plus(1, 2))

返回值的寫法雖說挺難看的吧,但支持tuple:

1
2
3
4
5
6
7
8
9
func requst(url: String)->(statusCode: Int, response: String)
{
    return (404, "Not Found!")
}

let (statusCode, message) = requst("http://google.com")

println(statusCode)
println(message)

覺得let (a,b) = function() 丑?沒關係,還有更優雅的寫法:

1
2
3
4
5
6
7
8
9
func requst(url: String)->(statusCode: Int, response: String)
{
    return (404, "Not Found!")
}

let result = requst("http://google.com")

println(result.statusCode)
println(result.response)

閉包(Closures)

和 js 差不多,直接是:

1
2
let a = {
}

但與js不同的是:他其實是下面代碼的縮寫

1
2
let a:()->() = {
}

也就是說,閉包其實是 Swift 的一種類型,寫作()->(),那麼他就可以當做 func 的參數嵌套了。寫成這樣:

1
2
3
4
5
6
7
8
func exec(repeat: Int, block:()->())
{
  for i in 1...repeat{
      block()
  }
}

exec(10, {println("Hello World")})

Swift 還提出了一個特殊的詞彙:Trailing Closures,他的意思是:如果閉包是func的最後一個傳參,那麼他可以寫在外面。如下:

1
2
3
4
5
6
7
8
9
10
func exec(repeat: Int, block:()->())
{
    for i in 1...repeat{
        block()
    }
}

exec(10){
    println("Hello World")
}

Comments