<値型>と<参照型>、<値渡し>と<参照渡し>がそろってる言語で実行例を出す
これで値の値渡しと値の参照渡しと参照の値渡しと参照の参照渡しの違いが分かっただろう
上記の投稿が単純明快ですばらしかったのでSwiftでも書いてみました。百の言葉で説明するより一つの実例の方がわかりやすいですね。
下記の四つの「実行結果」を見て、
- 値型
- 参照型
とは何か、
- 値の値渡し
- 参照の値渡し
- 値の参照渡し
- 参照の参照渡し
の違いは何かを理解できているかチェックしてみて下さい。
※ C言語版も作ったのでよかったらどうぞ。
実行コード
struct ValWrap { var value: Int = 0 }
class RefWrap { var value: Int = 0 }
func swapAndEdit(var left: ValWrap, var right: ValWrap) {
var tmp = left
left = right
right = tmp
tmp.value *= 100
}
func swapAndEdit(var left: RefWrap, var right: RefWrap) {
var tmp = left
left = right
right = tmp
tmp.value *= 100
}
func swapAndEdit(inout left: ValWrap, inout right: ValWrap ) {
var tmp = left
left = right
right = tmp
tmp.value *= 100
}
func swapAndEdit(inout left: RefWrap, inout right: RefWrap) {
var tmp = left
left = right
right = tmp
tmp.value *= 100
}
if true {
println("値の値渡し")
var left = ValWrap()
left.value = 1
var right = ValWrap()
right.value = 2
swapAndEdit(left, right)
println("\(left.value), \(right.value)")
}
if true {
println("参照の値渡し")
var left = RefWrap()
left.value = 1
var right = RefWrap()
right.value = 2
swapAndEdit(left, right)
println("\(left.value), \(right.value)")
}
if true {
println("値の参照渡し")
var left = ValWrap()
left.value = 1
var right = ValWrap()
right.value = 2
swapAndEdit(&left, &right)
println("\(left.value), \(right.value)")
}
if true {
println("参照の参照渡し")
var left = RefWrap()
left.value = 1
var right = RefWrap()
right.value = 2
swapAndEdit(&left, &right)
println("\(left.value), \(right.value)")
}
ValWrap や RefWrap は元記事からそのまま使ってますが、それぞれ value を Val (値型)で Wrap したもの、 value を Ref (参照型)で Wrap したものという意味だと思います(値をラップ、参照をラップではないです)。
実行結果
値の値渡し
1, 2
参照の値渡し
100, 2
値の参照渡し
2, 1
参照の参照渡し
2, 100