Swift In-Out 參數 (In-Out Parameters)
在 Swift 中,函式的參數預設是常數 (Constant),也就是說你不能在函式內部修改參數的值。如果你試圖修改,編譯器會報錯。
但有時候,我們會希望函式能修改傳入的變數,並且讓這個修改保留到函式外部。這時候就需要使用 In-Out 參數。
基本語法
1. 定義函式:使用 inout
在參數型別的前面加上 inout 關鍵字。
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
在這個例子中,swapTwoInts 函式接受兩個 inout 的整數。它會交換這兩個整數的值。
2. 呼叫函式:使用 &
當你呼叫一個接受 inout 參數的函式時,必須在傳入的變數名稱前面加上 & 符號 (Ampersand)。這表示原本的變數將會被修改。
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// 輸出 "someInt is now 107, and anotherInt is now 3"
運作原理:Copy-In Copy-Out
In-Out 參數的行為通常被描述為 Copy-In Copy-Out (或是 call by value result):
- Copy-In:當函式被呼叫時,參數的值被複製到函式內部。
- Modify:在函式執行期間,修改的是這個複本。
- Copy-Out:當函式執行結束時,這個複本的值被賦值回原本的變數。
雖然在編譯器最佳化後,為了效能可能會變成直接參考記憶體位址 (Call by Reference),但理解這個行為模型能幫助你避免一些副作用問題。
重要限制與規則
必須傳入變數 (
var):你不能傳入常數 (let) 或字面值 (Literal, 如1或"hello"),因為它們不能被修改。let constantNumber = 10 // swapTwoInts(&constantNumber, &anotherInt) // 錯誤!不能傳入 let // swapTwoInts(&10, &anotherInt) // 錯誤!不能傳入字面值不支援預設值:In-Out 參數不能有預設值。
不支援可變參數:可變參數 (Variadic Parameters,
...) 不能標記為inout。
常見應用場景
除了交換數值 (swap) 之外,常見的應用還包括:
- 修改複雜的 Struct 屬性。
- 在遞迴演算法中傳遞累加狀態。
- 某些高效能的數學運算。
Swift 標準庫中的 swap(_:_:) 函式就是使用 inout 實作的。
var myName = "Mike"
var yourName = "John"
swap(&myName, &yourName)