チャペルが参照によって引数を渡すかどうかは、引数intentによって制御できます。例えば、整数は通常、値渡しが、我々は、参照することによって1を渡すことができます:
proc increment(ref x:int) { // 'ref' here is an argument intent
x += 1;
}
var x:int = 5;
increment(x);
writeln(x); // outputs 6
方法をあなたは引数がデフォルトの意思として知られている指定されていない時に型が渡されます。チャペルは、デフォルトでレコード、ドメイン、および配列を参照渡しします。これらの配列の中でのみ、関数内で変更可能です。 (レコードとドメインがconst ref
を通過 - 彼らは参照によって渡されますが、それらはに渡される関数は、それらを変更することができないことを意味配列は、機能は彼らと何をするかに応じて、ref
またはconst ref
を通過 - 。array default intentを参照してください) 。
あなたの質問には、クラスインスタンスはデフォルトで "値"で渡されますが、チャペルはクラスインスタンスの "値"をポインタと見なします。つまり、フィールドを変更する代わりに、クラスインスタンスをref
で渡すだけで、別のクラスインスタンスに置き換えることができます。現在、クラスインスタンスのフィールドを関数内で変更できないようにする方法はありません(明示的に変更不可能なデータ型にすることを除く)。
このことを考えると、あなたが質問で提供したコードサンプルでは、私は非効率的ではありません。特に、ここで:
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
引数は、インスタンスへのポインタのコピーを受信しますb
を受け入れ、return b
はそのポインタのコピーを返します。インスタンスの内容(特にsecretIngredients
配列)は、元の場所に保存されたままであり、プロセスではコピーされません。
もう一つ:
この例では動作しますが、私が入力を「返却」していますので、それは悪い形のように思えます。
私が言ったように、これは実際にはクラスインスタンスや整数にとって問題ではありません。アレイはどうですか?この例では
proc identity(A) {
return A;
}
var A:[1..100] int;
writeln(identity(A));
、
identity()
で
return A
は、実際には配列のコピーがなされるべき
原因を行います。アレイがconst ref
インテントで渡されたため、アレイをidentity()
に渡すときにそのコピーが作成されませんでした。しかし、この関数は参照である "値で"何かを返すので、返り値の一部としてそれをコピーする必要があります。言語進化文書のarrays return by value by defaultも参照してください。いずれの場合においても 、1は参照によって配列を返すしたい場合、それはref
またはconst ref
リターンの意図、例えばでそうすることが可能です:
proc refIdentity(ref arg) ref {
return arg;
}
var B:[1..10] int;
writeln(refIdentity(B));
今の何のコピーはありません配列などはすべて同じものを指していますB
。
現在、もはや存在しない変数への参照を返すプログラムを書くことは可能ですが、コンパイラにはその領域のチェックが含まれていますが、完全ではありません。その地域での改善が間もなくできることを願っています。