Swift 學習筆記

Closure

Closure:無名的 Function

範例一,首先定義 Function,然後把它儲存在變數hi

func greeting() {
    println("hello world")
}
var hi = greeting

hi()   //output: hello world

範例二,直接定義 Closure 儲存在變數hi

var hi = { ()->() in
    println("hello world")
}

hi()   //output: hello world
  • Closure 不包含 Function 名稱。
  • Closure 語法把 Function 名稱右邊參數列與回傳型別放到{右邊然後加上in,其餘不變。
  • 儲存 Closure 變數的型別能從=右邊的 Closure 內容推測得知,型別定義可省略。

接受參數的 Closure

Closure 接受參數的用法與 Function 雷同。

var hi = { (name: String)->() in
    println("hello \(name)")
}

hi("hugo")   //output: hello hugo

當作參數的 Closure

Closure 當作參數的用法與 Function 雷同。

func repeat(count: Int, action: ()->()) {
    for _ in 1...count {
        action()
    }
}

repeat(3, {
    ()->() in
    println("hello world")  //output: hello world (3 times)
})

上面repeat呼叫方式可讀性不好,可以把傳入的 Closure 拉到()後面,這個技巧稱作 Trailing Closure。

func repeat(count: Int, action: ()->()) {
    for _ in 1...count {
        action()
    }
}

repeat(3) {
    ()->() in
    println("hello world")  //output: hello world (3 times)
}

上面 Closure 內的()->() in可以省略,因為參數型別已定義在action上。

func repeat(count: Int, action: ()->()) {
    for _ in 1...count {
        action()
    }
}

repeat(3) {
    println("hello world")  //output: hello world (3 times)
}

能省則省的 Closure

先來個囉唆的完整版。

func repeat(count: Int, action: (Int, String) -> String) {
    for i in 1...count {
        action(i, "hello")
    }
}

repeat(3) {
    (index: Int, message: String) -> String in
    return "第\(index)次說\(message)"
}
//output: 第1次說hello
//output: 第2次說hello
//output: 第3次說hello

以下範例省略回傳型別(回傳型別由action定義)。

repeat(3) {
    (index: Int, message: String) in
    return "第\(index)次說\(message)"
}

以下範例省略參數型別(參數型別由action定義)。

repeat(3) {
    index, message in
    return "第\(index)次說\(message)"
}

以下範例省略參數名稱(第一個參數名為$0, 第二個參數名為$1,以此類推)。

repeat(3) {
    return "第\($0)次說\($1)"
}

以下範例省略回傳動作return(Closure 最後一個 Statement 結果預設為回傳值,可不加return)。

repeat(3) {
    "第\($0)次說\($1)"
}

以下範例是最終精簡版本。

repeat(3) { "第\($0)次說\($1)" }