Go のポインターが関数の引数の変更を許可することは知っていますが、(適切な const または変更可能な修飾子を使用して) 参照のみを採用した場合は、より簡単ではないでしょうか。これでポインターができ、マップやチャネルなどの組み込み型の暗黙的な参照渡しができました。
何かが足りないのでしょうか、それとも Go のポインターは不要な複雑さなのでしょうか?
Go は簡潔で最小限の言語になるように設計されています。したがって、値とポインターだけで始まりました。その後、必要に応じて、いくつかの参照タイプ (スライス、マップ、およびチャネル) が追加されました。
The Go Programming Language : Language Design FAQ : 配列が値であるのに、マップ、スライス、およびチャネルが参照されるのはなぜですか?
「このトピックには多くの歴史があります。初期の頃、マップとチャネルは構文的にポインターであり、ポインター以外のインスタンスを宣言したり使用したりすることは不可能でした。また、配列がどのように機能するかについても苦労しました。最終的に、厳密に分離することを決定しました。ポインターと値の使用が言語の使用を困難にしました. 配列の参照形式を処理するためのスライスを含む参照型の導入により、これらの問題が解決されました. 参照型は、言語に残念な複雑さを追加しますが、使いやすさに大きな影響を与えます: Go はそれらが導入されたとき、より生産的で快適な言語。」
高速コンパイルは、Go プログラミング言語の主要な設計目標です。それにはコストがかかります。犠牲者の 1 つは、変数 (基本的なコンパイル時の定数を除く) とパラメーターを不変としてマークする機能のようです。リクエストされましたが、却下されました。
golang-nuts : go 言語。いくつかのフィードバックと疑問。
「型システムに const を追加すると、それがどこにでも表示されるようになり、何かが変更された場合はどこからでもそれを削除するように強制されます。何らかの方法でオブジェクトを不変であるとマークすることにはいくらかの利点があるかもしれませんが、const 型修飾子が適切であるとは考えていません。トーゴ。"
ポインターは再割り当てできますが、参照は再割り当てできません。これだけでも、参照を使用できない多くの状況でポインターが役立ちます。
「Go」のコンテキストで答えるのではなく、「ポインター」の概念を実装する任意の言語 (C、C++、Go など) のコンテキストでこの質問に答えます。「囲碁」にも同じ理屈が当てはまります。
通常、メモリ割り当てが行われるメモリ セクションは 2 つあります。ヒープ メモリとスタック メモリです (「グローバル セクション/メモリ」は文脈から外れるので含めないでください)。
ヒープ メモリ: Java、C#、Python など、ほとんどの言語で使用されているのはヒープ メモリですが、パフォーマンスに直接影響する「ガベージ コレクション」と呼ばれるペナルティが伴います。
スタック メモリ: C、C++、Go、Java などの言語のスタック メモリに変数を割り当てることができます。スタック メモリはガベージ コレクションを必要としません。したがって、ヒープメモリに代わるパフォーマンスの高い代替手段です。
しかし、問題があります。オブジェクトをヒープ メモリに割り当てると、「<em>複数のメソッド/関数」に渡すことができる「参照」が返されます。 /functions」は、同じオブジェクト(ヒープメモリに割り当てられた)を直接読み取り/更新できます。残念ながら、スタック メモリについては同じではありません。私たちが知っているように、スタック変数がメソッド/関数に渡されるときはいつでも、「ポインタの概念」(C、C++、Go の場合のように) があれば、それは「値渡し」(Java など) です。
ここでポインタが登場します。ポイントは、「複数のメソッド/関数」がスタックメモリに配置されたデータを読み取り/更新できるようにします。
一言で言えば、「<strong>ポインタ」は、「<strong>複数のメソッド/関数」によって変数/構造体/オブジェクトを処理するために、ヒープメモリの代わりに「<strong>スタックメモリ」を使用できます。したがって、ガベージ コレクション メカニズムによって引き起こされるパフォーマンス ヒットを回避します。
Go にポインターを導入するもう 1 つの理由は次のとおりです。Go は、C、C++、Rust などと同様に「効率的なシステム プログラミング言語」であるべきであり、多くのシステム コールと同様に、基盤となるオペレーティング システムによって提供されるシステム コールとスムーズに連携する必要があります。 API のプロトタイプにはポインターがあります。
システムコールインターフェースの上にポインターフリーレイヤーを導入することでそれが可能になると主張する人もいるかもしれません。はい、それは可能ですが、ポインターを持つことは、優れたシステム プログラミング言語の特徴であるシステム コール レイヤーのすぐ近くで動作するようなものです。