これでスッキリ!Ruby/JS/PHP/Go「参照渡し・値渡し」完全比較
「あれ?関数の中で変えたら、外の値まで変わってる!?」
プログラミングしてて一度は出会うこの謎。
今回は、主要4言語 ― Ruby、JavaScript、PHP、Go ― について、関数引数の挙動(値渡し or 参照渡し)を徹底的に比較してみました!
🧠 1. Ruby ― すべてはオブジェクト。参照が基本
Rubyでは、変数はすべて「オブジェクトへの参照」を持っています。
def change(hash)
hash[:x] = 999
return hash
end
[2] pry(main)> params = { x: 1 }
=> {:x=>1}
[3] pry(main)> prms = change(params)
=> {:x=>999}
[4] pry(main)> puts params[:x]
999
=> nil
[5] pry(main)> puts prms
{:x=>999}
=> nil
[6] pry(main)> puts params
{:x=>999}
=> nil
👆関数内で変更すると、外の値まで変わる!
✅ 防ぎたいなら .dup
safe = params.dup
safe[:x] = 999 # params は変わらない
🔧 オブジェクトの**破壊的変更(mutability)**に注意!
🌐 2. JavaScript ― 参照型と値型で挙動が違う!
JavaScriptでは、オブジェクトと配列は参照渡し風の動きをします。
function change(obj) {
obj.x = 999;
}
let data = { x: 1 };
change(data);
console.log(data.x); // => 999
✅ 防ぎたいならスプレッド構文でコピー
let copy = { ...data };
🧠 JSでもプリミティブ型(number, string など)は値渡しです!
🐘 3. PHP ― 配列は値渡し、オブジェクトは参照渡し!
PHPはちょっと独特。配列は値渡しが基本です。
function change($arr) {
$arr['x'] = 999;
}
$params = ['x' => 1];
change($params);
echo $params['x']; // => 1 ❗️
でも、オブジェクトは参照的です。
class Data { public $x = 1; }
function change($obj) {
$obj->x = 999;
}
$data = new Data();
change($data);
echo $data->x; // => 999
✅ 配列やオブジェクトを明示的に参照渡しするには?
function change(&$arr) {
$arr['x'] = 999;
}
🚀 4. Go ― 常に値渡し。でも中身が変わる?!
Goは基本的に「全ての引数は値渡し」です。ただし...
🔸 スライスとマップは内部にポインタを含む!
func modify(s []int) {
s[0] = 999
}
func main() {
arr := []int{1, 2, 3}
modify(arr)
fmt.Println(arr[0]) // => 999 ❗️
}
🔸 構造体は完全にコピー
type Data struct { X int }
func modify(d Data) {
d.X = 999
}
d := Data{X: 1}
modify(d)
fmt.Println(d.X) // => 1 ❌
✅ 中身も変えたいならポインタを渡す
func modify(d *Data) {
d.X = 999
}
📌 最終比較まとめ表
言語 | 配列・マップ(または類似) | オブジェクト | 変更を防ぐ方法 |
---|---|---|---|
Ruby | 参照渡し | 参照渡し | .dup , .clone |
JS | 参照渡し風 | 参照渡し風 | {...obj} , Array.slice() |
PHP | 値渡し(配列) | 参照渡し | clone , &$var |
Go | 値渡し(でも中身は共有) | 値渡し | ポインタ *T , make/copy |
✨ 終わりに
プログラミング言語ごとに異なる「引数の渡し方」は、設計ミスやバグの温床になりがち。でも、それぞれにちゃんとした設計意図とメリットがあるんですね。
あなたの今の言語だけじゃなく、他の言語も理解すれば、もっとバグに強く、設計力の高いエンジニアになれます💪💻
🧙♂️ この記事が参考になったら、他の言語比較シリーズもぜひチェックしてくださいね!
(もっと言語ごとの実装パターンなど知りたければお気軽にコメントを♪)
登録日:
更新日:
by
プログラマーこまつ