2016-11-24 2 views
2

私は "The Go Programming Language"という本を読んでいます。経験豊富なプログラマーにとっては非常に良い経験であり、他の言語の共通部分の違いについて説明していますが、私が完全に理解していないケースが見つかりました。構造体リテラルに移動しますが、なぜこのアドレス可能ですか?

私はC++が十分に優れていることを知っていますが、Go呼び出し(C++では何が呼び出されるか)はrvalues/xvalues "non-addressable"と理解しています。 "変数" [GOPLの言葉]のみがアドレス可能です。

OK、十分です。それは理にかなっている。

従って、例えば、これは、(最初​​の印刷のページ159による)違法である

Point{1, 2}.ScaleBy(2) // compile error: can't take address of Point literal 

(*Point).ScaleByは、受信引数として*Pointをとり、そしてPointリテラルは、非アドレス指定可能であるためです。

(あなたが本を読んでいない場合は、PointはフィールドX, Y float64を持つ構造体である。

しかし、162ページ、我々は明らかに有効であり、意志である

type ColoredPoint struct { 
    *Point 
    Color color.RGBA 
} 

p := ColoredPoint(&Point{1, 1}, red) 
// ...more code ... 

を持っていますコンパイル

質問:。

2番目のケースのPointリテラルがアドレス可能なのはなぜですか?

便宜のために特別なケースですか、大きな画像に何かを見逃していますか?

答えて

3

&T{}表記は、セクション4.4.1で説明され、構造体リテラル、ページの103:

構造体は、その一般的に、それが作成および初期化構造体の変数を、そのアドレスを取得するために、この省略表記を使用することが可能ですが、ポインタを介して扱われているので:

pp := &Point{1, 2} 

それは

pp := new(Point) 
*pp = Point{1, 2} 

しかし&Point{1, 2}とまったく同じであるが、このような関数呼び出しとして、式の中で直接使用することができます。

他にもこの本を楽しんでいると嬉しいです。

+0

私はそれを本当に楽しんでいます!私は仕事を非常にすぐにフルタイムで書くことになる可能性が高いので、私は(多かれ少なかれ急いで)それを読んでいます。この部分を欠落している必要があります。私はこれがK&Dとそこにあると思う....私はK &R. ;を意味する - )もう一度ありがとう! – Tobias

3

便宜上、特殊なケースです。仕様には例外hereが含まれています。

アドレス可能性要件の例外として、xは(おそらく括弧でくくられた)コンポジットリテラルでもかまいません。メロウマーモットの答えにもう少し詳細を追加する

+0

ありがとう、これは明らかに私の質問に直接答えです。私はそれをすぐにそのようにマークします。 – Tobias

3

Spec: Variables:

組み込み関数newを電話またはcomposite literalのアドレスを取るには、実行時に変数のストレージを割り当てます。このような匿名変数は、(おそらく暗黙的に)pointer indirectionを介して参照されます。

Point{1, 1}はコンポジットリテラルです。そのアドレスはフードの下に匿名変数を作成し、式の結果はこの匿名変数のアドレスになります。

だから、あなたが技術的に見ることができるように、アドレス指定され変数ですので、これに違反していない:

のみ「変数」 [GOPLの言葉]がアドレス可能です。また

あなたが行うことができ、他のどのような「グッズ」やトリックを確認するには、この答えをチェックアウト:How do I do a literal *int64 in Go?

+0

受け入れていただきありがとうございます!非常に有用な情報。 – Tobias

関連する問題