在 SwiftUI 裏閉包出現的頻率特別高,這裏我從新梳理了下閉包的定義。swift
閉包表達式語法的通常形式以下:api
{(parameters) -> return type in // 代碼 } 複製代碼
閉包表達式寫在花括號({})裏,關鍵字in用來分隔閉包的參數、返回值與閉包體內的語句markdown
// 傳遞閉包個 sort 方法 arr.sort(by: { (a: Int, b: Int) -> Bool in return a > b }) // 閉包能夠利用 Swift 的類型推斷能力,能夠省略返回類型,以及參數的類型 arr.sort(by: { a, b in return a > b }) // 這裏移除了關鍵字return。不是全部的閉包語句均可以移除 return 關鍵字 // 這裏能夠是 由於只有一個表達式 (i < j)。若是存在更多表達式,那麼顯式的 return 就是必需的。 arr.sort(by: { a, b in a > b }) // Swift 提供了快捷參數名,能夠在內聯閉包 表達式中使用 arr.sort(by: { $0 > $1}) // 若是一個閉包是以一個函數的最後一個參數傳遞的,那麼它就能夠在函數的圓括號之外內聯。 arr.sort { $0 > $1 } 複製代碼
// 普通方式 var str: String = "str" // 閉包運行賦值 var str2: String = { return "str2" }() // 基於閉包原理簡化 var str3: String = { "str3" }() // 若是不須要傳遞實參,閉包體前的"="號,和末尾的"()"也能夠省略 var str4: String { "str4" } 複製代碼
在聲明式的 UI 建立裏大量使用閉包,好比閉包
import SwiftUI struct Text: View { var body: some View { Button(action: { print("Button Click") }) { Text("Hello World!") } } } 複製代碼
這裏建立 View、Button 都使用了閉包,看了下 Button 的實現,以下函數
public struct Button<Label> : View where Label : View { /// Creates an instance for triggering `action`. /// /// - Parameters: /// - action: The action to perform when `self` is triggered. /// - label: A view that describes the effect of calling `action`. public init(action: @escaping () -> Void, @ViewBuilder label: () -> Label) /// Declares the content and behavior of this view. public var body: some View { get } /// The type of view representing the body of this view. /// /// When you create a custom view, Swift infers this type from your /// implementation of the required `body` property. public typealias Body = some View } 複製代碼
在 init 方法裏設置了 2 個參數,都是函數類型,在使用時能夠利用 swift 的 尾部閉包語法
:若是一個閉包是以一個函數的最後一個參數傳遞的,那麼它就能夠在函數的圓括號之外內聯,因此 Button 能夠如此寫ui
Button(action: { print("Button Click") }) { Text("Hello World!") } 複製代碼
也能夠這樣寫this
Button(action: { print("Button Click") }, label: { Text("Hello World!") }) 複製代碼