closure 參數的省略,神奇的 $0,$1 & $2 (Shorthand Argument Names)
Swift 的 closure 有很多精簡省略的寫法,幫助我們加班打 code 不再手酸。接下來我們將介紹其中最特別,最像火星文的參數省略寫法,Shorthand Argument Names。
當 closure { } 的程式碼欲存取傳入的參數時, 可透過內建的秘密代號存取,$0 代表第一個參數,$1 代表第二個參數,其它以此類推。當我們透過 $0、$1 存取,原本的參數宣告也就沒有存在的價值,因此我們可以一口氣將 closure 的參數,回傳型別 & in 全部移除 !
比方以下程式將 array songs 用 shuffle 隨機排序,然後呼叫 function firstIndex(where:),找出 happySong 在 array songs 裡的位置。
struct Song {
let name: String
let singer: String
}
let happySong = Song(name: "有點甜", singer: "汪蘇瀧")
let sadSong = Song(name: "苦笑", singer: "汪蘇瀧")
var songs = [happySong, sadSong]
songs.shuffle()
let happySongIndex = songs.firstIndex { song in
song.name == happySong.name
}
省略參數的例子: firstIndex & sorted
我們可以在呼叫 firstIndex 時採用參數省略的寫法,改用 $0 存取 songs 裡的歌,將參數,回傳型別 & in 全都省略。
let happySongIndex = songs.firstIndex {
$0.name == happySong.name
}
array 呼叫排序的 sorted function 時也可以省略參數,由於它有兩個參數,所以我們以 $0.grade > $1.grade
指定 array 裡分數高的學生排在前面。
struct Student {
let name: String
let grade: Int
}
var students = [Student(name: "Hook", grade: 52), Student(name: "Peter", grade: 98)]
students = students.sorted {
$0.grade > $1.grade
}
透過 $0、$1 存取參數十分精簡,但這樣子的精簡不見得好,因為它將讓程式的可讀性變差,不易看出參數代表的意義。因此除非在類似剛剛的 firstIndex & sorted 例子,不會對程式可讀性造成影響時,才適合採用如此精簡的做法。
closure 參數省略的注意事項
一旦採用如此極致的精簡,連參數也移除,有一個額外的規定也要遵守。在 closure 的 { } 裡一定要使用 $ 搭配最大數字的秘密代號,因為此數字將決定 closure 接收的參數數量。
以 firstIndex 為例,closure 裡要用到 $0,因為 closure 接收的參數數量是 1 個。
以 sorted 為例,closure 裡要用到 $1,因為 closure 接收的參數數量是 2 個。
一旦決心要殺人,就要斬草除根,否則可是會春風吹又生。同樣的道理,若要省略參數,必須連之後的回傳型別和 in 一併省略。在 closure 的 { } 裡若是沒有參數, 只有回傳型別和 in,將冒出我們最不想看到的紅色錯誤。