回答
inout
表示修改局部變量也會修改傳入的參數。沒有它,傳入的參數將保持相同的值。嘗試在使用inout
時使用參考類型,而不使用值類型。
例如:
import UIKit
var num1: Int = 1
var char1: Character = "a"
func changeNumber(var num: Int) {
num = 2
print(num) // 2
print(num1) // 1
}
changeNumber(num1)
func changeChar(inout char: Character) {
char = "b"
print(char) // b
print(char1) // b
}
changeChar(&char1)
良好的使用情況將是swap
函數,它將修改傳入的參數。
斯威夫特3+注意:Starting in Swift 3,在inout
關鍵字一定要來冒號後和類型之前。例如,Swift 3+現在需要func changeChar(char: inout Character)
。
從Apple Language Reference: Declarations - In-Out Parameters:
作爲一種優化,當參數是存儲在存儲器中的物理地址 的值,相同的存儲器位置所使用的函數身體外部的內部和 。優化的行爲稱爲 參考;它滿足了複製 複製模型的所有要求,同時消除了複製的開銷。不要依賴 對拷入拷貝和撥打 參考之間的行爲差異。
如果你有一個函數,它接受一個有些記憶明智的大值類型作爲參數(比如,一個大的結構型),並返回相同類型,最後當函數返回始終只是用來替換調用者參數,那麼inout
就是優選的關聯函數參數。
考慮下面的例子中,在註釋說明爲什麼我們要使用inout
比普通型的回報型功能在這裏:
struct MyStruct {
private var myInt: Int = 1
// ... lots and lots of stored properties
mutating func increaseMyInt() {
myInt += 1
}
}
/* call to function _copies_ argument to function property 'myHugeStruct' (copy 1)
function property is mutated
function returns a copy of mutated property to caller (copy 2) */
func myFunc(var myHugeStruct: MyStruct) -> MyStruct {
myHugeStruct.increaseMyInt()
return myHugeStruct
}
/* call-by-reference, no value copy overhead due to inout opimization */
func myFuncWithLessCopyOverhead(inout myHugeStruct: MyStruct) {
myHugeStruct.increaseMyInt()
}
var a = MyStruct()
a = myFunc(a) // copy, copy: overhead
myFuncWithLessCopyOverhead(&a) // call by reference: no memory reallocation
此外,在上面的例子---無視內存問題--- inout
可以優先考慮告訴誰讀取我們的代碼,我們正在修改函數調用者參數(由函數調用中參數前面的&符號&
隱式顯示)。下面總結了相當整齊:如果你想有一個函數來修改參數的值
,並希望 這些變化將持續函數調用結束後,確定 該參數爲IN-OUT參數,而不是。
從Apple Language Guide: Functions - In-Out Parameters。
有關inout
以及如何在內存中的實際處理(名稱copy-in-copy-out
有些誤導......)---在額外的鏈接到語種導遊上述---看到下面的SO線程的詳細信息:
(編輯另外:附加的註釋)
在盧卡斯黃接受的答案給出上面的例子試圖---在使用inout
參數的函數的範圍---訪問作爲inout
參數被傳遞,該變量。這是不推薦,並明確警告不要在語言裁判做:
不要訪問是作爲在-out參數傳遞的值,即使 原來的說法是在當前可用範圍。當 函數返回,你原來的變化是覆蓋與 複製的價值。 不要依賴於 的call-by-參考優化的實施,儘量保持變化被 覆蓋。
現在,在這種情況下的訪問是「唯一的」不可變的,例如, print(...)
,但按照慣例,所有這樣的訪問都應該避免。
在從評論者的要求,我加入了一個例子時,爲什麼我們真的不應該做「這是作爲一個在出參數傳遞的價值」的東西閃耀光芒。
struct MyStruct {
var myStructsIntProperty: Int = 1
mutating func myNotVeryThoughtThroughInoutFunction (inout myInt: Int) {
myStructsIntProperty += 1
/* What happens here? 'myInt' inout parameter is passed to this
function by argument 'myStructsIntProperty' from _this_ instance
of the MyStruct structure. Hence, we're trying to increase the
value of the inout argument. Since the swift docs describe inout
as a "call by reference" type as well as a "copy-in-copy-out"
method, this behaviour is somewhat undefined (at least avoidable).
After the function has been called: will the value of
myStructsIntProperty have been increased by 1 or 2? (answer: 1) */
myInt += 1
}
func myInoutFunction (inout myInt: Int) {
myInt += 1
}
}
var a = MyStruct()
print(a.myStructsIntProperty) // 1
a.myInoutFunction(&a.myStructsIntProperty)
print(a.myStructsIntProperty) // 2
a.myInoutFunction(&a.myStructsIntProperty)
print(a.myStructsIntProperty) // 3 or 4? prints 3.
因此,在這種情況下,INOUT表現爲複製在複製出(而不是由參考)。我們總結了重複從語言參考文檔以下語句:
不要依賴於複製在複製出 之間的行爲差異,並通過引用調用。
通過使用INOUT參數就可以改變一個值類型參數的數據,並隨時更改均保持不變的函數調用結束後。
- 1. 如何打印inout參數?
- 2. OUT或INOUT參數不起作用
- 3. 在gwt中使用rpc時,如何將參數類型設置爲inout?
- 4. 在Oracle,PL/SQL中使用INOUT參數的過程示例
- 5. 存儲過程IN,OUT,INOUT參數
- 6. 將記錄收集爲INOUT參數
- 7. 作爲inout參數的不可變值
- 8. INOUT參數崩潰雨燕編譯
- 9. C#是否支持inout參數?
- 10. 消氣意外呼籲INOUT參數的第二時間
- 11. 駱駝sql存儲組件。如何傳遞INOUT oracle參數?
- 12. 如何在SQL Server中捕獲Oracle SP INOUT參數
- 13. inout參數 - 用另一個替換一個常量句柄
- 14. 如何在PostgreSQL中消除多個INOUT參數的函數調用
- 15. 如何在數組的每個元素上使用`inout`參數調用一個函數?
- 16. 通過INOUT參數返回數組無需修改
- 17. 如何調用休眠4存儲過程的參數IN OUT INOUT模式,
- 18. 如何從前端設置INOUT參數,而調用存儲過程
- 19. 作爲INOUT或OUT參數需要的動態參數或變量
- 20. 在使用雨燕INOUT可選
- 21. 避免在VHDL中使用inout
- 22. 何時使用引用在C++參數
- 23. 如何使用inout參數和Swift中的返回類型爲void來返回函數?
- 24. 使用Verilog inout電線時遇到問題
- 25. 可分配意圖(inout)參數是否可選?
- 26. 什麼是Objective-C相當於Swift的inout參數?
- 27. MySQL從c中存儲過程接收inout參數#
- 28. swift inout參數是變量還是指針?
- 29. PHP MySQL PDO存儲過程和INOUT參數
- 30. IN,OUT或INOUT對於程序中的參數無效
你確定這種情況的發生與您在傳遞的「常規」參數以及基本類型? – Thilo
您是否有代碼示例顯示Swift的行爲如您所描述的那樣? – Thilo
查看我的示例@Thilo –