傳值Call by Value 與 傳址 Call by Reference
學過c++的一定會遇到
傳值與傳址
一開始聽到整個
wtf 這兩個是尛阿
到最近看了一下ref跟out之後才比較了解
一般資料型別分為兩種
一個是實質型別
一個是參考型別
測試看看
實質型別就是 int float char…等基礎的型別
而他變數記憶體存放的內容是”值“所以稱為實”值“型別
也就是”傳值“,當你在使用他的時候
他們之間傳遞的方式都是把值copy一份後再傳進去
像是以下
1 | int A=5, B=10; |
之後在Start方法內調用
1 | Debug.Log(" A :" + A + " b :" + B); |
下圖分別是將AB傳進去前跟傳進去後的結果
可以看到傳進去後值都沒改變,這是因為使用的方式只是傳值(call by value)而已
意思就是把“值”複製給對方,而複製完改變的東西並不會影響到本身的值,因此不會做任何改變
而下面對照
1 | Car car11 = new Car("car11"); |
同樣的宣告 同樣的方法 同樣在Start內打上
1 | Debug.Log(" car11 :" + car11._carName + " car22 :" + car22._carName); |
出來的結果則為
結果卻改變了,因此從上可以推論出來Car是一個傳址Call by Reference
意思就是,它傳遞的不是複製一份出來的值,而是傳遞丟入物件的記憶體位址
然後間接透過它來操作物件,跟指標很類似。
其實在C/C++的時候 正確是有三個名詞的
call by value 傳值、call by reference 傳參考、call by address傳址
但由於這裡要講的是C#,所以用官方的翻譯來敘述 ->
如果要詳細了解這三個有什麼差別 可以再去google
ref、out
ref 關鍵字
會導致引數由參考加以傳遞,而非透過值。
參考程式碼 :
1 | class RefExample |
可以發現實質類型使用ref關鍵字之後,就會變得像是上面參考類型一樣
可以修改傳入的參數了
1 | class RefExample |
那問題來了,參考類型本身傳遞就可以直接修改值了
為何還會使用ref關鍵字加到參考型別身上呢?
- 明確提示
加了之後 不管給別人用還是自己用 都可以知道 傳入的參數是會被改變值得
不管傳入實質或參考都一樣 - string的不變性 參考連結
- 為了修改默認值類型
- ref重點:
- 傳遞至 ref 參數的引數,在傳遞之前必須先初始化。
- 不能將ref和out用於async修飾詞定義的非同步方法。
- 有進有出
out 關鍵字
基本上跟ref一樣
想要多個回傳值的時候,可以使用out
1 | class OutReturnExample |
ref跟out在使用上有很微小的差距
使用out的話,他不需要在被調用前初始化
但是調用者需要在返回之前指定輸出的參數
另一方面,可以用這樣去想
out類似於將方法附加返回值,也就是回傳多個值