3

Dlang は out パラメータを次のように説明します。

関数のエントリ時にその型の既定値で初期化されるパラメーター。

パラメータが関数エントリのデフォルト値で初期化された後、それは本質的に単なるref?

import std.stdio;

void foo(out int x)
{
    writeln(x); //prints 0
    x = 2;
}

void main()
{
    int x = 1;
    writeln(x); //prints 1
    foo(x);
    writeln(x); //prints 2
} 

outと比較するドキュメントはありませんref。パラメータを記述からのショートカットとして
概念化することは正確ですか?out

import std.stdio;

void foo(ref int x)
{
    x = x.init; //happens implicitly
    writeln(x); //prints 0
    x = 2;
}

void main()
{
    int x = 1;
    writeln(x); //prints 1
    foo(x);
    writeln(x); //prints 2
}

私はその言語の複雑さを知らないので、このような印象を持っていると、将来不測の事態が発生した場合に悲しみに暮れるのではないかと心配しています.

これらをより明確に区別できますかparameter storage classes、それとも自動的に再初期化されるのは本当に ref パラメータですか?

4

2 に答える 2

2

はい、今日実装されているのはこれだけですが、意味的にはそれだけではありません。

paramsoutは、従来の意味での引数ではなく、追加の戻り値と考えれば問題ありません。関数は戻り値のアドレスを受け取ることも、それを介してデータを受け取ることもできません。out パラメーターは、これらの方法でも使用しないでください。


D は を持っていませんでしたref。代わりに、 、 、および をパラメータ ストレージ クラスとして使用inoutましinoutた。

inつまり、参照することを意味しますが、それへの参照を変更または保存しないことを意味します (後者は、それを区別するものconstです-保存は許可されていますが、またはparamsは許可されてconstいません。コンパイラは、理論的にはそれらのメモリ割り当てを最適化します)。それはデータ消費のためだけです。inscope

out関数がその変数にデータを保存することを意味しますが、それを調べたり保存したりすることはありません。関数がその結果を書き込むと、事前にそこにある値は失われます。コンパイラは、プログラムが渡された値に依存しないことを保証するために、関数のエントリ時にそれをリセットします。

最後に、以前inoutはデータを取り込み、値を保存していました。今日 (まあ、5 年前のように始まりました)、この使用法はとうの昔になくなっており、inoutまったく別のことを意味しています (constただし、constness を返すことは入力を条件としています。const/immutable/mutable 修飾子は in と同じ out を持っています)。使用法は に置き換えられref、意味も拡張されました。これは、データの出入りではなく、別の変数への本格的な参照であり、アドレスの取得などの操作が許可されていることを意味します。

outはプラスの自動再初期化として実装されていrefますが、元の意味を覚えておく必要があります。データを書き込むだけで、他には何もしません。そのアドレスを使用しないでください。これは (または...refでない限り) では有効ですが、 では正しくありません。あなたはそれに書くことになっています、それ以上は何もありません。scope refin refout

于 2015-12-19T03:32:33.220 に答える
2

out パラメーターは、値が暗黙的に再初期化される ref ですか?

はい。

パラメータが関数エントリのデフォルト値で初期化された後、それは本質的に単なる参照ではありませんか?

はい。

これらのパラメーター ストレージ クラスをより明確に区別できますか?それとも、自動的に再初期化されるのは本当に ref パラメーターですか?

後者。少なくとも、私はそう考えています。何かを見逃していないことを願っています。

于 2015-12-18T22:59:51.223 に答える