2016-05-20 12 views
0

私はstructポインタの使用を好むべきかどうか、構造体の配列に関する質問があります。Golangでリストの構造体ポインタを使用したいのですか?

たとえば、アイテムの配列を含むItemとCartがあるとします。

type Item struct { 
    Id   string 
    Name  string 
    Price  string 
} 

type Cart1 struct { 
    Id   string 
    Items  []Item 
} 

または

type Cart2 struct { 
    Id   string 
    Items  []*Item 
} 

私たちは、構造体のリストに構造体を追加する場合、golangはコピーを作成し、リストに追加し、これは必要ありませんので、我々はのリストを使用する必要がありますことを聞きました構造体ポインタ、それは本当ですか?

誰でも明示できますか?

答えて

1

Go配列は値渡し、goはスライスがポインタのように参照渡しされます。事実スライスには、内部データ型の一部としてポインタが含まれています。カートにはさまざまなアイテムがありますので、[]Itemを使用してください。

は、スライスは、容量4を持って、あなたがそれに何か第五の事を追加した場合、Goは容量を倍増するので、すべての単一の添加は、あなたは右のあなたの中にあるメモリ

+0

質問は、アレイまたはスライスの_element_タイプについて質問します。アレイまたはスライスを使用するかどうかは問いません。 – icza

+0

@iczaこの答えのように、XYの問題を解決しようとしているようです - OPは「アイテムの配列やポインタの配列」と言っていますが、「Goの慣用的な解決策は何か」と暗黙のうちに言われています。スライス。文字通りOPの質問に答えた人がいれば、SOは決して役に立たないだろう – dwanderson

3

を割り当てます好きではないですBTW this effective go reference

を参照してください。仮定 - 任意の(append())関数アプリケーションのコピーだけでなく、値渡しの引数がGoに渡されました。しかし、どのようにポインタのスライスがメモリ消費量を減らすでしょうか?実際の構造体+参照をメモリに格納する必要があります。参照はアクセス制御に関するものです。

foo := cart1.Items[0] 
foo.Name := "foo" //will not change cart1 
//but in pointer case 
bar := cart2.Items[0] 
bar.Name := "bar" //will change cart2.Items[0].Name to "bar" 
0

あなたの質問を理解しているので、あなたはメモリ消費ではなく構造体の不要なコピーです。

Goのすべてが値渡しです。もしあなたが構造体のスライスを持っていて、新しい構造体を追加するなら、Goはコピーを作成します。構造体のサイズによっては、大きすぎることがあります。代わりに、構造体へのポインタのスライスを使用することもできます。こうすると、Goを追加するとポインタのコピーが作成されます。

これは安いかもしれませんが、スライスにアクセスするコードが複雑になることもあります。なぜならあなたはconstポインタを持つことができず、誰でも構造体を変更することができるGoで特に問題となるmutable状態を共有しているからです。また、ポインタには参照解除エラーが発生しないようになっています。

どちらを選択するかは、あなた次第です。ここには一つの "行く方法"はありません。

関連する問題