(section01-05 データ型から抜粋)
関数の引数に渡す値がプリミティブ型なのかリファレンス型なのかにも注意が必要です。プリミティブ型の変数を引数として渡したときは、関数の中でその引数に対して操作しても元の変数には影響がでません。一方、リファレンス型の変数を関数の引数として渡した場合には、関数の中で引数の値を変更すると元の変数の値が変化してしまいます。
値渡し(プリミティブ型)
次の例では価格と個数から金額を計算するkeisan()を使っています。keisan()では変数tankaの値を引数kakakuで受け、それに個数を掛けた値をそのままkakakuの値として上書きしてます。結果を見るとわかるように演算後の変数tankaの値は2400のまま変化していません。
[:script:]引数で渡した変数は変化しない
参照渡し(リファレンス型)
次の例は最小値を調べるためにArray型の変数を引数で渡した結果、元の配列の並びが変化してしまう例です。Arrya型の変数pricesを作り、数字の並びを配列として代入します。8行目以降で定義してあるgetMin()は引数で受けとった配列の中の最小値を調べて返す関数です。このとき、getMin()は引数vlistで受けた配列の値をvlist.sort()を実行して直接並べ替えています。この結果、2行目が実行されると最小値が変数lowPriceに代入されるだけではなく、引数として与えたpricesの値の並びも変えてしまうことになります。
[:script:]引数で渡した変数に入っていた配列の並びが変化してしまう
関数の引数に渡す値がプリミティブ型なのかリファレンス型なのかにも注意が必要です。プリミティブ型の変数を引数として渡したときは、関数の中でその引数に対して操作しても元の変数には影響がでません。一方、リファレンス型の変数を関数の引数として渡した場合には、関数の中で引数の値を変更すると元の変数の値が変化してしまいます。
値渡し(プリミティブ型)
次の例では価格と個数から金額を計算するkeisan()を使っています。keisan()では変数tankaの値を引数kakakuで受け、それに個数を掛けた値をそのままkakakuの値として上書きしてます。結果を見るとわかるように演算後の変数tankaの値は2400のまま変化していません。
[:script:]引数で渡した変数は変化しない
var tanka:int = 2400; var kingaku:int = keisan(tanka, 2); //結果を調べる trace(tanka); //出力:2400 trace(kingaku); //出力:4800 //引数で渡された変数を使って計算する function keisan(kakaku:int, kosu:int):int { kakaku = kakaku * kosu; return kakaku; }
参照渡し(リファレンス型)
次の例は最小値を調べるためにArray型の変数を引数で渡した結果、元の配列の並びが変化してしまう例です。Arrya型の変数pricesを作り、数字の並びを配列として代入します。8行目以降で定義してあるgetMin()は引数で受けとった配列の中の最小値を調べて返す関数です。このとき、getMin()は引数vlistで受けた配列の値をvlist.sort()を実行して直接並べ替えています。この結果、2行目が実行されると最小値が変数lowPriceに代入されるだけではなく、引数として与えたpricesの値の並びも変えてしまうことになります。
[:script:]引数で渡した変数に入っていた配列の並びが変化してしまう
var prices:Array = [20, 56, 12, 40]; var lowPrice:int= getMin(prices); //結果を調べる trace(prices); //12,20,40,56 trace(lowPrice); //12 //引数で渡された変数を使って計算する function getMin(vlist:Array):int { //vlistをソートする vlist.sort(); //1番目の値を返す return vlist[0]; }
*補足*
じゃあ、リファレンス型の値を引数に渡すにはどうすればいいのかという問題ですが、引数を受け取って処理するfunctionで値を複製し、元の値を使わずに処理を行うようにします。多くのクラスはインスタンス自身を複製するclone()メソッドをもちますが、その理由はここにあります。
ただ、Arrayクラスにはclone()がありません。Arrayクラスではslice()を使って配列を複製します。先のgetMin()を引数の配列が変化しないように修正すると次のようになります。
[:script:]引数で渡した配列が変化しないように複製して使う
じゃあ、リファレンス型の値を引数に渡すにはどうすればいいのかという問題ですが、引数を受け取って処理するfunctionで値を複製し、元の値を使わずに処理を行うようにします。多くのクラスはインスタンス自身を複製するclone()メソッドをもちますが、その理由はここにあります。
ただ、Arrayクラスにはclone()がありません。Arrayクラスではslice()を使って配列を複製します。先のgetMin()を引数の配列が変化しないように修正すると次のようになります。
[:script:]引数で渡した配列が変化しないように複製して使う
var prices:Array = [20, 56, 12, 40]; var lowPrice:int= getMin(prices); //結果を調べる trace(prices); //20,56,12,40 trace(lowPrice); //12 //引数で渡された配列を複製して使う function getMin(vlist:Array):int { //配列vlistを複製する var tmpList:Array=vlist.slice(); //tmpListをソートする tmpList.sort(); //1番目の値を返す return tmpList[0]; }配列の複製について、詳しくは書籍のp.109を参照してください。