2016-04-25 10 views
0

私は幾分奇妙なコードを書きましたが、なぜそれが働くのか、私はそれから学ぶことができるのか分かりません。私は別の構造体からスライス型のビルドを持っています。スライスタイプで機能を修正しました。これを行うには、私はちょっと捨てなければならないようです。これらのポインタで何が起こっていますか?

私はGoのポインタについて学びたいと思っていますし、少し助けてください。ここでは一例(http://play.golang.org/p/roU3MEeT3q)です:*これらのそれぞれの目的は何ですか、なぜ私はどんな&を使用していない:

var ClientNames = []string {"Client A", "Client B", "ClientC"} 


type InvoiceSummaries []InvoiceSummary 
type InvoiceSummary struct { 
    Client string 
    Amt int 
} 

func (summaries *InvoiceSummaries) BuildFromAbove() { 
    for _, name := range ClientNames { 
     *summaries = append(*summaries, InvoiceSummary{name, 100}) 
    } 
} 

私の質問はありますか?

+2

注意。セレクタを介して構造体フィールドにアクセスすると、値が自動的に参照解除されます。 – JimB

答えて

1

それぞれの目的は何ですか?

メソッドレシーバーをポインターにすることで、オブジェクトのプロパティーを簡単に変更できます。私はそれが利益の1つだと思う。以下の例はそれを証明します。

package main 

import "fmt" 

type someStruct struct { 
    someVar int 
} 

func (s someStruct) changeVal1(newVal int) { 
    s.someVar = newVal 
} 

func (s *someStruct) changeVal2(newVal int) { 
    s.someVar = newVal 
} 

func main() { 
    s := someStruct{0} 
    fmt.Println(s) // {0} 

    s.changeVal1(3) 
    fmt.Println(s) // {0} 

    s.changeVal2(4) 
    fmt.Println(s) // {4} 

    (&s).changeVal2(5) 
    fmt.Println(s) // {5} 
} 

、なぜ私はどんな&を使用していないのですか?

ポインタメソッドレシーバは非常に特殊ですが、非ポインタ構造体オブジェクトからも呼び出すことができます。 s.changeVal2(4)(&s).changeVal2(5)の両方が有効な&の場合、someVarの値に影響します。

例ほとんどのユーザーのタイプは構造体になりがちので、この問題は、しばしば見られないことをhttp://play.golang.org/p/sxCnCD2D6d

1

受信者のポインタを使用する必要があります。それ以外の場合は、引数が値渡しされるため、ポインタを使用すると値の参照が渡されるためです。そうでなければ、コレクションをまったく変更できませんでした。

メソッド本体の内部には、逆戻り演算子でありアドレスの値を返すため、*が使用されています。アンパサンド(&)は反対で、値のアドレスを与えます。

+0

ああ。そうですか。だから、私はポインタを宣言したりデリファレンスをするために*を使うのですか?私は受信機にそれ以上心配する必要がないと思ったので、私はそれを仮定しました。 – Walt

+0

@Walt JimBさんがあなたの質問にコメントで説明しました。構造体では自動的に処理されるので、頻繁に実行されることはありませんが、組み込み型の場合は必要です。 – evanmcdonnal

1

コードに間違いはありませんが、通常はスライスへのアドレスは使用されません。スライスは、gophersが通常は値渡しをしてくれる小さな構造体です。メソッドや関数が新しいスライスを作成している場合、gopherは戻り値として新しいスライスを値で再び返すことができます。

もちろん、値でスライスを渡しても、メソッド/関数が返されたときにバッキングストアが変更されないことは保証されません。したがって、スライスのデータ要素が変更されていないことを保証する方法として使用することはできません。

関連する問題