這篇文章為 Stanford CS193p - Developing Apps for iOS Lecture 2 課程筆記
Swift 為 functional programming,會很頻繁的使用到function作為參數傳遞到其他function。
以下演示進行closure的思維步驟,以對 EmojiMemoryGame.model 的初始化為例
Closure: the inlining of function in swift
1.定義 function createCardContent(),將createCardContent作為初始化MemeryGame的參數
struct MemeryGame<CardContent> {
struct Card {
var showUp : Bool
var isMatched : Bool
var content : CardContent
}
var cards : Array<Card>
init (numberOfCardPairs : Int, cardContentFactory : (Int)->CardContent) {
cards = Array<Card>()
for pairIndex in 0..<numberOfCardPairs {
let content = cardContentFactory(pairIndex)
cards.append(Card(showUp: false, isMatched: false, content : content))
cards.append(Card(showUp: false, isMatched: false, content : content))
}
}
}
func createCardContent(pairIndex : Int) -> String {
"card string"
}
class EmojiMemoryGame {
private var model : MemeryGame<String> =
MemeryGame<String>(numberOfCardPairs: 2, cardContentFactory: createCardContent)
}
2.除去function name
不需要實際定義 function createCardContent(),而是以funciton的實際內容取代createCardContent,並以{ }框住整個inline function。
使用 in 隔開參數和function的內容。
private var model : MemeryGame<String> =
MemeryGame<String>(numberOfCardPairs: 2,
cardContentFactory: { (pairIndex : Int) -> String in "card string" })
3.Swift 有型別推斷(type inference)的功能
因為 cardContentFactory 的 function type 為 (Int)->CardContent
因此可以將 inline function 定義 type 的部分移除,原本包覆pairIndex的()也可省略
private var model : MemeryGame<String> =
MemeryGame<String>(numberOfCardPairs: 2,
cardContentFactory: { pairIndex in "card string" })
4.當 function 最後的參數使用 { } 傳入, 可以調整為
- 移除keyword cardContentFactory
- 將 { } 移到外部
private var model : MemeryGame<String> =
MemeryGame<String>(numberOfCardPairs: 2) { pairIndex in "card string" }
5.使用 underbar _ 簡化未使用到的參數
pairIndex 是不會改變function所回傳結果的參數(不管pairIndex數值為何,皆 return "card string"), 因此可以使用 _ 取代
在Swift中,不會影響function或不會使用到的參數會使用 _ 代替進行簡化。
private var model : MemeryGame<String> =
MemeryGame<String>(numberOfCardPairs: 2) { _ in "card string" }