配列は関数に渡すと参照で渡される。
myarray = ["dog", "cat", "flower"];
function show_array(_array) {
show_debug_message(_array[1]);
}
show_array(myarray);
cat と出力される。
しかし渡した配列を変更しようとすると、関数内でコピーが作られる。returnで元の配列myarrayに返してやらないと、myarrayは更新されない。下記を実行するとどうなるか。
myarray = ["dog", "cat", "flower"];
function rewrite_array(_array) {
show_debug_message("(1) _array[1]="+string(_array[1]));
_array[1] = "food";
show_debug_message("(2) _array[1]="+string(_array[1]));
}
rewrite_array(myarray);
show_debug_message("(3) myarray[1]="+string(myarray[1]));
(1) _array[1]=cat
(2) _array[1]=food
(3) myarray[1]=cat
と出力される。元のmyarrayは変更されていない。
そこで、関数内で配列アクセッサ@を使う。これで関数内から配列を直接更新できる。
myarray = ["dog", "cat", "flower"];
function rewrite_array(_array) {
show_debug_message("(1) _array[1]="+string(_array[1]));
_array[@ 1] = "food";
show_debug_message("(2) _array[1]="+string(_array[1]));
}
rewrite_array(myarray);
show_debug_message("(3) myarray[1]="+string(myarray[1]));
結果。
(1) _array[1]=cat
(2) _array[1]=food
(3) myarray[1]=food
元の配列myarrayが変更された。
コピーを作り(自動で作られる)、それを変更し、元の配列に返して更新する というのは手間がかかる。オーバーヘッドも生じる。
なので@を使って直接変更すればいいよという話でした。
array = array2;
みたいな代入だとコピーされるんですかね?
array2 = array1
やってみました。
関数に渡したときと同じことが起きてるように見えます。
つまり、
array2 = array1
でarray2はarray1の参照になり、array2を変更しようとした時点でコピーされ別の配列になる。結果
(1) array1 = [ "dog","cat","flower" ]
(1) array2 = [ "dog","cat","flower" ]
(2) array1 = [ "dog","cat","flower" ]
(2) array2 = [ "dog","123","flower" ]
array2だけが変更されている。ということはコピーされていてarray1とarray2は別の配列になっていると見ることができる。
★1の部分を array2[@ 1] = "123"; にすると、
結果
(1) array1 = [ "dog","cat","flower" ]
(1) array2 = [ "dog","cat","flower" ]
(2) array1 = [ "dog","123","flower" ]
(2) array2 = [ "dog","123","flower" ]
array1とarray2が両方変わっている
array2はarray1の参照のままであり、array2[@ 1]でarray1[1]を直接変更したと考えられる。
★1の部分を array1[1] = "123"; にすると、
結果
(1) array1 = [ "dog","cat","flower" ]
(1) array2 = [ "dog","cat","flower" ]
(2) array1 = [ "dog","123","flower" ]
(2) array2 = [ "dog","123","flower" ]
array1とarray2が両方変更されている
array2はarray1の参照であるからarray1の内容を示していると考えられる。
なるほど
この辺の仕様が、Version 2022.2.0.614 で変更されるそうです。
詳しくはリリースノートを。
https://gms.yoyogames.com/ReleaseNotes.html
ブログにも情報ありました。
https://www.yoyogames.com/en/blog/release-2022-2
(記事終盤のCOPY ON WRITE OPTIONの箇所)