10

私は Go を学んでいますが、ポインターをいつ使用するかについて少し混乱しています。具体的にはstruct、関数から a を返す場合、いつ構造体インスタンス自体を返すのが適切で、いつ構造体へのポインターを返すのが適切ですか?

コード例:

type Car struct {
  make string
  model string
}

func Whatever() {
  var car Car

  car := Car{"honda", "civic"}

  // ...

  return car
}

ポインターを返したい状況と、したくない状況は何ですか? 良い経験則はありますか?

4

3 に答える 3

18

留意すべき点が 2 つあります。それは、パフォーマンスと API です。

車はどのように使われますか? 状態を持つオブジェクトですか?大きな構造体ですか?残念ながら、車が何かわからないと答えられません。正直なところ、最善の方法は、他の人が何をしているかを見て、それらをコピーすることです. 最終的には、このような感覚に陥ります。ここで、標準ライブラリの 3 つの例を説明し、それらが使用したと思われる理由を説明します。

  1. hash/crc32:crc32.NewIEEE()関数はポインター型を返します (実際にはインターフェイスですが、基になる型はポインターです)。ハッシュ関数のインスタンスには状態があります。情報をハッシュに書き込むと、データが合計されるため、メソッドを呼び出すと、Sum()その 1 つのインスタンスの状態が得られます。

  2. time:time.Date関数は構造体を返しますTime。なんで?時間は時間です。状態はありません。これは、それらを比較したり、計算を実行したりできる整数のようなものです。API 設計者は、時刻を変更しても現在の時刻は変更されず、新しい時刻が作成されると判断しました。ライブラリのユーザーとして、今から 1 か月後の時間が必要な場合は、現在の時間オブジェクトを変更するのではなく、新しい時間オブジェクトが必要です。時間の長さもわずか 3 語です。つまり、サイズが小さく、ポインターを使用してもパフォーマンスは向上しません。

  3. math/big: big.NewInt()は興味深いものです。を変更するbig.Intと、新しいものが必要になることがよくあります。Abig.Intには内部状態がないのに、なぜポインターなのですか? 答えは単純にパフォーマンスです。プログラマーは、big int が… 大きいことに気付きました。数学演算を行うたびに常に割り当てることは、実用的ではない場合があります。そこで、ポインターを使用して、プログラマーがいつ新しいスペースを割り当てるかを決定できるようにすることにしました。

私はあなたの質問に答えましたか?おそらくそうではありません。これは設計上の決定であり、ケースバイケースで判断する必要があります。独自のライブラリを設計するときは、標準ライブラリをガイドとして使用します。本当にすべては、判断と、クライアント コードが型をどのように使用することを期待するかにかかっています。

于 2012-06-12T04:26:32.593 に答える
2

多くの場合、状態を格納する「オブジェクト」とオブジェクトを変更できる「メソッド」があるオブジェクト指向スタイルを模倣したい場合、構造体 (他の OO 言語のように「オブジェクト参照」と考えてください)。Mutator メソッドは、「オブジェクト」のフィールドを変更するために、構造体型自体ではなく、構造体へのポインター型のメソッドである必要があるため、構造体の代わりに構造体へのポインターがあると便利です。すべての「メソッド」がそのメソッド セットに含まれるようにします。

たとえば、Java で次のようなものを模倣するには、次のようにします。

class Car {
  String make;
  String model;
  public Car(String myMake) { make = myMake; }
  public setMake(String newMake) { make = newMake; }
}

Go では、次のようなものをよく見かけます。

type Car struct {
  make string
  model string
}
func NewCar(myMake string) *Car {
  return &Car{myMake, ""}
}
func (self *Car) setMake(newMake string) {
  self.make = newMake
}
于 2012-06-11T23:44:21.473 に答える
2

非常に大雑把ですが、特定の状況で例外が発生する可能性があります。

  • 値が非常に小さい (数単語以下) 場合に値を返します。
  • コピーのオーバーヘッドがパフォーマンスを大幅に低下させる場合 (サイズは多くの単語)、ポインターを返します。
于 2012-06-11T20:35:57.910 に答える