設計者は他に何も見たことがない であるため、値渡しは初期の言語からの遺産であると常に思っていました。しかし、Goのような新しい言語を見て、同じ原則を採用すると、私は混乱しました。
私が考えることができる唯一の利点は、渡す値が変更されないようにすることです。ただし、大きな構造体を関数に渡す必要がある場合は常に、言語で許可されている場合は、コピーを防ぐためにポインター(または参照)を渡す必要があります。
パラメータの変更を防ぐために、言語全体を値渡しする代わりに、いくつかのconst
nessメカニズムを導入できます。
私は何年もコーディングしてきましたが、価値を渡す必要はほとんどありませんでした。ほとんどの場合、値/オブジェクトを関数呼び出しにコピーする必要はありません。多くの場合、関数内で変更する必要はありません*。
現代の言語を価値のあるものにする理由は何ですか?私が知らない利点はありますか?
編集:値渡しと言っても、プリミティブを意味しているわけではありません。値で渡すのは簡単で安価です。私の主な焦点は、2つ以上のプリミティブで構成されるオブジェクトまたは構造体であり、コピーするのに高価です。
*:私は周りに尋ねました、そして他の人はそれらのパラメータの使い方で同様のことを報告しました。
参照渡しは、いくつかのことをより効率的にし、サブルーチン内のパラメーターの更新を可能にしますが、決して万能薬ではありません。
並列化されたアプリケーションを想像してください。参照渡しを使用する場合は、正常な状態を維持するためのロックメカニズムが必要です。値渡しにはこの制限はありません。データの処理よりもミューテックスの待機に多くの時間を費やすマルチスレッドプログラムを見てきました。ここで、値渡しは効率を大幅に向上させることができます。
分散アプリケーションを想像してみてください。リモートシステムはオブジェクトの独自のコピーを必要とするため、これは常に値渡しです。参照渡しは、プロキシオブジェクトを使用してシミュレートする必要があります。プロキシオブジェクトの同期を維持するには、追加のネットワークオーバーヘッドが必要です。ここで値渡しは、処理時間を節約するだけでなく、ネットワーク帯域幅を削減します。
値による受け渡しは、値のセマンティクス(つまり、値による変数、オブジェクトメンバーなど)の単なる帰結です。あなたが言及する利点の他に、これは追加します:
struct Foo { T a; U b; }
のようなタイプでは、メンバーに個別の割り当てや追加の間接指定は必要ありません。class IntWithDifferentBehavior { int value; ... }
は、メソッドの静的ディスパッチを想定して、int
とまったく同じくらい効率的です。さらに、値渡しはmuchより簡単で、メモリを安全かつ効率的にします。ポインタ/参照をスタックに割り当てられたメモリに渡す場合、メモリが参照よりも長く存続することを確認する必要があります。代わりに自動メモリ管理を使用してそれを保証する場合は、実行時に料金を支払います。
デザイナーは他に何も見たことがないので、値渡しは初期の言語からの遺産であるといつも思っていました。
これは、2つの点で偽の特性です。
値渡しは元々の受け渡しの形式であり、より優れたものに置き換えられたものと想定しています。実際、歴史はこれが真実ではないことを明確に示しています(出典として引用した回答もそうです)。
これは、主流のプログラミング言語の設計者がプログラミング言語の履歴を無知であることを(論理的な論拠や裏付けのない証拠なしに)意味します。関連ドキュメントを適切にレビューすると、この概念は完全に偽...関係者への侮辱は言うまでもないことがわかります。
参照渡し、値渡し、および/または不明瞭/履歴形式(パス渡しや名前渡しなど)の1つをサポートするという実際の決定は、他の側面と深く絡み合っています。全体的な言語設計...そして、設計の目標に動機づけられています。
例えば:
プログラムが読みやすく理解しやすい言語を提供することが目標ですか?
「表現力」や「簡潔さ」を最大限に引き出す言葉を提供することが目標ですか?
特定の種類の問題に対する「パフォーマンス」を最大化する言語を提供することが目標ですか?
他よりも特定のプログラミング「パラダイム」をサポートすることが目標です。例えば手続き型、オブジェクト指向、関数型、純粋な関数型、並列/同時?
等々。
つまり、「値渡しの利点」のような単純な考え方をはるかに超えています。
私は何年もコーディングしてきましたが、価値を渡す必要はほとんどありませんでした。ほとんどの場合、値/オブジェクトを関数呼び出しにコピーする必要はありません。
何かが意味をなさない...
Java、C、C++、C#、または他のほとんどの最新のプログラミング言語で何年もコーディングしている場合、ほとんどの場合sing値渡しです。これは、物事を行うためのデフォルトの方法です...そして、一部の言語(Javaなど)では、それが唯一の方法です。
例えば
int i = 1;
myFunction(i);
AFAIK、i
は、C、C++、JavaおよびC#)の値で渡されます。参照渡し(CおよびC++)が必要な場合は、明示的に記述する必要があります。例えば.
myOtherFunction(&i);
あなたはコードで実際にそれをいつもしていますか?プリミティブ型付き変数の場合?私はそうは思いません。