web-dev-qa-db-ja.com

Goに「新しい」機能があるのはなぜですか?

Goにnewがある理由にはまだ戸惑っています。

構造体をインスタンス化したいときは、

_t := Thing{}
_

あなたは新しいインスタンスへのポインタを得ることができます

_t := &Thing{}
_

しかし、この可能性もあります:

_t := new(Thing)
_

この最後のものは、言語の他の部分には少し異質なようです。 _&Thing{}_はnew(Thing)と同じくらい明確で簡潔であり、他の場所でよく使用する構造体のみを使用します。また、_&Thing{3}_または_&Thing{Feets:7}_に変更する可能性があるため、より拡張性があります。

私の意見では、補足的なキーワードを持つこと1 コストがかかり、言語がより複雑になり、知っておく必要のあることが追加されます。また、構造体のインスタンス化の背後にあるものを新規参入者に隠すかもしれません。

また、予約語をもう1つ作成します。

newの背後にある理由は何ですか?時々役に立ちますか?それを使用する必要がありますか?


1 :はい、私はそれが文法レベルのキーワードではないことを知っています あなたはそれを隠すことができます 、しかしそれはそれが合理的な開発者にとって予約語であるという事実を変えません。

53
Denys Séguret

質問する最良の方法は、おそらくその作業をしている人々にあるでしょう。正確に 私がやった

Tl; dr:元々はmake&{}の前にありましたが、一部の状況で使用する関数です

基本的に、ここに引用されている最も重要な部分があります:

それで、新しい理由は何ですか?何か便利ですか?それを使用する必要がありますか?

あなたはこれなしでこれを行うことはできません

v := new(int)
*v++
fmt.Println(*v)

newはGoのヘッドライン機能ではありません。頻繁に使用されることはありませんが、必要なときに使用できます。

乾杯

デイブ

この種のソリューションを示す別の回答の後:

vv := 0
v := &vv
*v++
fmt.Println(*v)

さらに説明を求めました:

だから、基本的に、デイブの主張は実際には成り立ちませんか?

アドレスを取得するためだけに新しい変数に忍び込むのは不便な場所があります。

new(T)は、マルチステップのイディオムではなく、直接的な意味を持っています。

Daveの主張は、技術的な可能性(newなしで実行できる)が単独で説得力がある場合にのみ当てはまります。

これは、ほとんどすべての言語が持っているのでGoが持っているべきであることが明白だったので、議論されていませんでしたか?

「私たちはnewを守らなければなりませんか?」議論は時々ポップアップします。 Go 2までは取り出せないので、Promiseを正しく理解していれば、ループを再び回る必要はあまりないようです。 Go 2が考えられる頃には、いくつかの異なるより良いアイデアがあるかもしれません...

クリス

また、主に歴史的な理由からも存在します。

プロジェクトの履歴を考慮する必要があります。メイクがある前に新しいものが最初に導入されると思います。

それは本当です。実際、私たちはメイクのアイデアを思いつく前に、しばらく苦労しました。リポジトリログを見ると、makeが2009年1月のリビジョン9a924177598fにのみ表示されていることがわかります。

新しい組み込み関数はまた、複合リテラルのアドレスを取得するための&{}のアイデアの前にもありました(そしてその構文はある意味で間違っています。おそらく(* T){fields of T}であるべきですが、十分ではありませんでしたそれを変更する理由)。

新しい関数は厳密には必要ありませんが、コードは実際にはそれを使用しているようです。この時点でそれを取り除くのは難しいです。

イアン

48

Peano.goでは、次のことを行います。

type Number *Number
func add1(x *Number) *Number  {
     e := new(Number)
     *e = x
     return e
}

そして、「new」を使わずにそれを書き直して同じ結果を得ることができました:

type Number *Number
func add1(x *Number) *Number {
     var e Number
     e = x
     return &e
}

したがって、この非常に特殊なケースであっても、まったく必要ないようです。

0
Gzorg