🏠 ホーム
フロントエンド
PHP
Go言語
プログラミングの理解
プログラマーへの道
Google API

これでスッキリ!Ruby/JS/PHP/Go「参照渡し・値渡し」完全比較

  プログラミング >     PHP >  

「あれ?関数の中で変えたら、外の値まで変わってる!?」

プログラミングしてて一度は出会うこの謎。

今回は、主要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

コメント         tweetでコメント