はじめに
D言語には、静的配列と動的配列があります。
コピー処理を意識せずに行うと、想定外の動きとなります。(かつての私のように)
C言語の場合
C言語で配列をコピーする場合の実装例は、以下の通りかと思います。
コピー後、配列t
の値を書き換えています。
結果として、配列s
と配列t
の値は異なっています。
copysample.c
#include <stdio.h>
intmain(void){ints[3]={1,2,3};intt[3];// t = s とはできないmemcpy(t,s,sizeof(s));printf("s = %d %d %d\n",s[0],s[1],s[2]);printf("t = %d %d %d\n",t[0],t[1],t[2]);t[1]=4;printf("s = %d %d %d\n",s[0],s[1],s[2]);printf("t = %d %d %d\n",t[0],t[1],t[2]);}
実行結果
s = 1 2 3
t = 1 2 3
s = 1 2 3
t = 1 4 3
D言語の場合
D言語では、t = s
を使ったコピーが可能ですが、静的配列と動的配列で実行結果が異なります。
int[3]は、静的配列です。先ほどのC言語の場合と同じ実行結果になります。
copysample1.d
importstd.stdio;voidmain(){int[3]s=[1,2,3];int[3]t;t=s;writefln("s = %s",s);writefln("t = %s",t);t[1]=4;writefln("s = %s",s);writefln("t = %s",t);}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 2, 3]
t = [1, 4, 3]
int[]
は、動的配列です。
先ほどとは実行結果が異なり、配列s
と配列t
の値が同じになっています。
copysample2.d
importstd.stdio;voidmain(){int[]s=[1,2,3];int[]t;t=s;writefln("s = %s",s);writefln("t = %s",t);t[1]=4;writefln("s = %s",s);writefln("t = %s",t);}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 4, 3]
t = [1, 4, 3]
copysample1.dの静的配列では、ディープコピー、
copysample2.dの動的配列では、シャローコピーが行われています。用語補足
では、動的配列をディープコピーしたい場合はどうすればいいのか。
D言語では、.dup
というプロパティが用意されています。
copysample3.d
importstd.stdio;voidmain(){int[]s=[1,2,3];int[]t;t=s.dup;writefln("s = %s",s);writefln("t = %s",t);t[1]=4;writefln("s = %s",s);writefln("t = %s",t);}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 2, 3]
t = [1, 4, 3]
おまけの注意点
D言語には、もう1つ連想配列というものがあります。
連想配列のコピーは基本的に動的配列と同じですが、連想配列の要素がない空の状態でのコピーはnull
がセットされるだけで、シャローコピーにはならない点に注意です。
D言語のサイト(英語)
参考情報
他のプログラミング言語はどうかと思い、調べてみました。
リンク先 |
---|
Java |
JavaScript |
C# |
go |
ruby |
Python |
PHP |