function 関数名($引数A, $値A) { $変数A = $引数A;←この場合は、値を変更していないので、値のコピーは行われず、時間もかからない return $変数A; }
function 関数名($引数A, $値A) { $変数A = $引数A; $変数A = $値A;←これでも引数Aの値のコピーが行われる。変数Aと引数Aで同じメモリ領域を見てる? return $変数A; } ------------------------------------------------------------------------------------------------------- [サンプルプログラムその2] *3 class クラス名 { public function メソッド名($引数A, $値A) { $引数A = $値A;←メソッドにしても所詮は値渡しされた引数の中身を変えているので結果は変わらない return $引数A; } }
$変数A = 値B; $変数B = new クラス名(); $変数A = 変数B->メソッド名($変数A, 値C); ------------------------------------------------------------------------------------------------------- [サンプルプログラムその3] class クラス名 { public function コンストラクタ() { $this->init(); } public function init() { $this->set_変数A(null); } public function set_変数A($変数B) { $this->変数A = $変数B; } public function get_変数A() { return $this->変数A; } public function メソッド名($値A) { $this->変数A = $値A; } private $変数A; }
$変数C = new クラス名(); $変数C->set_変数A(値B); $変数C->メソッド名(値C); // 値を取得したければ「$変数C->get_変数A()」
値渡ししていても、その引数の中身を操作していないので問題ない ------------------------------------------------------------------------------------------------------- で、終わりのはずが・・・ ------------------------------------------------------------------------------------------------------- [前回のブログ記事のはてブにこんなのが] 理屈では知っていても、結果を見ると改めて驚かされますね。ただ速度を考慮しないのであれば、参照渡しとか破壊系のメソッドとかは使いたくないしなぁ。 ←破壊系のメソッドってなぁに? ------------------------------------------------------------------------------------------------------- [破壊系のメソッド] ・オブジェクトの内部状態(値)を変えてしまうメソッド ・Rubyに多いみたい ・例えば、「$str = 'a';」の時、「$str->小文字を大文字に変えるメソッド();」を実行し、「戻り値がない」のに、$strが'A'になる様なメソッド ・つまり、自分で自分のクラスのメソッドを呼んでるのに、自分の内部状態を変えてしまうメソッド(ミュータブル的とも言う) ------------------------------------------------------------------------------------------------------- [非破壊系のメソッド] ・オブジェクトの内部状態(値)を変えないメソッド ・さっきと逆で、内部状態を変えたい時には、戻り値が必要 ・例えば、「$str = 'a';」の時、「$str = $str->小文字を大文字に変えるメソッド();」を実行すると、$strが'A'になる様なメソッド ・つまり、自分で自分のクラスのメソッドを呼ぶだけでは、自分の内部状態は変わらないメソッド(イミュータブル的とも言う) ------------------------------------------------------------------------------------------------------- [で・・・] ・破壊的(ミュータブル的)と参照渡しとオブジェクト指向 ・非破壊的(イミュータブル的)と値渡しと非オブジェクト指向 ・これらって似てないか? ・前者はオブジェクトの状態が「変わる」が、後者は「変わらない」って角度で見たときに ------------------------------------------------------------------------------------------------------- [イミュータブルなクラスのサンプル] final class クラス名 { public function コンストラクタ($変数A) { $this->変数B = $変数Aをディープコピーする; } public function get_変数B() { return $変数Bをディープコピーする; } public function メソッド名($値A) { new 自分のクラス名($値A); } private final(PHPは変数にfinal書けないけど) $変数B; }
$変数C = new クラス名(値B); $変数C->メソッド名(値C); // 値を取得したければ「$変数C->get_変数A()」