たとえば、数値の 2 つのベクトルを (数学的な意味で) 加算したいとします。当然、私は次のようなことをします:
T[] add(T)(T[] a, T[] b) {
assert(a.length == b.length);
T[] res = a.dup;
foreach (i; 0 .. a.length) {
res[i] = a[i] + b[i];
}
return res;
}
まあ、大丈夫ですが、すべての呼び出しを疑っa
てb
コピーしますが、これはそれほど素晴らしいことではありません。だから私はそれらを宣言しますref
。
T[] add(T)(ref T[] a, ref T[] b) { ...
変数を渡している間はうまく機能しますが、テストでは配列インスタンスを使用します。
assert(add([1, 2, 3], [4, 5, 6]) == [5, 7, 9]);
そして、配列の参照を推測できないため、これは失敗します。私は回避策を見つけることができました:
T[] add(T)(T[] a, T[] b) {
return add(a, b);
}
問題を解決しているように見えますが、かなりばかげています。私の問題に適した設計は何ですか?
ref
または、それをより小さな質問に入れます:コピーを避けるために引数を宣言する必要は本当にありますか? コンパイラーは、私が変更a
したりb
、これを最適化したりしないので、私のためにこれを最適化できますか? ちなみに、引数を不変と宣言するにはどうすればよいですか(immutable
キーワードを試しましたが、間違って使用しているようです)?res
回避策で本当に 2 回コピーされますか、それとも移動によって返品されますか?