Swift3 之函數參數的新變化

今天,在看 Then 源碼時,發現了一處比較值得研究的地方

public func with(_ block: (inout Self) -> Void) -> Self {
    var copy = self
    block(&copy)
    return copy
}

這部分代碼是在針對 Any 類型的協議擴展里實現的。這里 with 的語義是拷貝值類型并修改(代碼中針對的是 Any,這里用值類型來說明問題)。可以看看官方的示例:

let newFrame = oldFrame.with { 
    $0.size.width = 200 
    $0.size.height = 100
}
newFrame.width // 200
newFrame.height // 100

注意,這里使用的是 inout 關鍵字,而且已經把它的位置放在了類型之前,這是 Swift3 的新變化 Adjusting inout Declarations for Type Decoration

在函數調用時,如果傳遞的參數是引用類型,那么我們在函數中對參數的修改會直接影響到傳進來的變量,這就是函數的副作用。

然而,如果傳遞的參數是值類型的話,我們在函數中對參數是不可以進行修改的,因為傳參時函數會創建一個不變量來存儲值,我們不可以對這個不變量進行修改。在 Swift2 中有個關鍵字 var 可以讓函數創建一個變量來存儲值,這樣我們就可以在函數中對這個變量進行修改了。不過在 Swift3 中已經去掉了這個關鍵字 Removing var from Function Parameters

如果想讓值類型具備引用類型的語義,這時 inout 關鍵字就出場了。這個有點類似 C 語言中傳遞指針,我們在調用時需要加上 & 標識。這樣,我們就可以愉快的對值類型進行修改了。不過,為了避免函數副作用,我們最后不要這樣做。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容