12

Goツアーの 28ページと53 ページによる

これらは、構造体リテラルへのポインターである変数を示しています。これがデフォルトの動作ではないのはなぜですか? 私は C に慣れていないので、理解するのが難しいです。ポインターを使用することがより有益ではない可能性がある唯一の場合は、構造体リテラルが一意であり、残りのプログラムで使用されないため、できるだけ早くガベージコレクションする必要がある場合です. Go のような現代的な言語がそのように機能するかどうかさえわかりません。

私の質問はこれです。構造体リテラルへのポインターを変数に割り当てる必要があるのはいつですか? また、いつ構造体リテラル自体を割り当てる必要がありますか?

ありがとう。

4

2 に答える 2

13

構造体リテラルの代わりにポインタを使用すると、次の場合に役立ちます。

  • 構造体が大きく、あなたはそれを回します
  • あなたはそれを共有したい、つまり、すべての変更はコピーに影響を与えるのではなく、構造体に影響を与えるということです

それ以外の場合は、構造体リテラルを使用するだけで問題ありません。int小さな構造体の場合、または:を使用するのと同じように質問について考えることができます*int。ほとんどの場合、intは問題ありませんが、レシーバーがint変数を変更できるようにポインターを渡すこともあります。

リンク先のGoツアーの演習では、頂点構造体は小さく、他の数値とほぼ同じセマンティクスを持っています。私の意見では、それを構造体として直接使用し、次のように#53Scaledで関数を定義することは問題ありませんでした:

func (v Vertex) Scaled(f float64) Vertex {
    v.X = v.X * f
    v.Y = v.Y * f
    return v
}

持っているので

v2 := v1.Scaled(5)

のように新しい頂点を作成します

var f2 float32 = f1 * 5

新しいを作成しfloatます。

これは、標準の構造体(ここでTime定義)の処理方法に似ています。これは通常、ではなく型の変数に保持されます。Time*Time

しかし、明確なルールはなく、用途によっては、との両方Scaleを維持できたはずScaledです。

于 2012-12-07T10:17:12.770 に答える
2

ほとんどの場合、ポインターが必要なのはおそらく正しいですが、個人的には、明示的なポインターが必要であると感じています。intと の間に違いがないようにしMyStructます。彼らは同じように振る舞います。

これをC#(あなたが提案しているものを実装する言語)と比較すると、これのセマンティクスが混乱していることがわかります。

static void SomeFunction(Point p)
{
    p.x = 1;
}
static void Main()
{
    Point p = new Point();
    SomeFunction(p);
    // what is p.x?
}

が aまたは aPointとして定義されているかどうかに依存します。classstruct

于 2012-12-09T00:37:49.000 に答える