func printIntNum(add: (Int, Int) -> Int, a: Int, b: Int) {
print("num = \(add(a, b))")
}
參數 add 的類型是 (Int, Int) -> Int,即「接受兩個 Int 返回 Int 的函數類型」。
| 維度 | 函數類型作參數 | 閉包 |
|---|---|---|
| 定義視角 | 類型系統視角:參數類型為函數簽名 | 語法/語義視角:匿名函數 + 環境捕獲能力 |
| 可傳入內容 | 具名函數、匿名函數(閉包)、方法引用 | 僅指匿名函數字面量({ ... }) |
| 捕獲上下文 | 不關心,只要簽名匹配即可 | 核心特徵:可捕獲外層作用域變量/常量 |
| 代碼示例 | func add(_ a:Int,_ b:Int)->Int {a+b} printIntNum(add: add, a:1, b:2) | printIntNum(add: { $0 + $1 }, a:1, b:2) |
Swift 中**函數是一等公民**,具名函數本質上也是一種閉包(捕獲環境為空的閉包)。函數類型 (Int,Int)->Int 統一描述了「兩個 Int 進,一個 Int 出」的所有可調用實體,無論它是 func 定義還是 {} 字面量。
printIntNum(a:1, b:2) { $0 + $1 }@escaping:閉包在函數返回後才被調用(如異步回調),需標記:func asyncAdd(_ a:Int,_ b:Int, completion:@escaping (Int)->Void)@autoclosure:自動將表達式包裝為閉包:func log(_ message:@autoclosure ()->String) { print(message()) } 調用時 log("expensive \(compute())"),compute() 僅在需要時執行。// 網絡請求回調
func request(url: String, completion: @escaping (Data?, Error?) -> Void) { ... }
// 排序策略注入
func sort(_ array: [Int], by comparator: (Int, Int) -> Bool) -> [Int] { ... }
sort(nums, by: >) // 傳入運算符函數
sort(nums, by: { $0 % 2 == 0 && $1 % 2 != 0 }) // 傳入閉包邏輯
func printIntNum(add: (Int, Int) -> Int, ...) 中的 add 參數類型是**函數類型**,表示「這裡需要一個兩進一出的可調用對象」。調用時既可傳**具名函數**,也可傳**閉包字面量**。閉包只是「帶環境捕獲能力的匿名函數」的一種寫法。**兩者無本質區別,只是叫法視角不同**。