2017-07-28 8 views
0

最近、私はから "Go Programming Blueprints"のソースコードを公開しました。 googleGeometry構造は、リテラルの代わりにポインタを使用し、そして、そのような宣言の背後にある理由は何である理由私は理解していない何カスタム構造内のポインタ

type googleGeometry stuct { 
    *googleLocation `json:"location"` 
} 
type googleLocation struct { 
    Lat float64 `json:"lat"` 
    Lng float64 `json:"lng"` 
} 

はありますか?

ポインタの代わりに以下の宣言が必要です。

type googleGeometry stuct { 
    gl googleLocation `json:"location"` 
} 
+0

*埋め込み型ではなく、構造体のメンバーです。そこには区別がありますが、この場合には単純な構造体ではなくポインタがなぜ選択されたのかはまだ分かりません。 – captncraig

+0

@captncraigまだstructメンバーです。 [埋め込み型は一種の構造体メンバです](https://golang.org/ref/spec#Struct_types)。 – Adrian

答えて

0

googleGeometry埋め込むgoogleLocationへのポインタ。本質的に名前のないフィールドであるため、LatフィールドとLngフィールドは最上位のフィールドのようにアクセスできます。

なぜ

type googleGeometry stuct { 
    *googleLocation `json:"location"` 
} 

代わり

type googleGeometry stuct { 
    googleLocation `json:"location"` 
} 

のでしょうか?

私は彼らが間違ってここに電話したと思う。あなたが行うので、もしポインタがnil可能です:

g := googleGeometry{} 
fmt.Println(g.Lat) 

あなたがnilリファレンスパニックを取得します。ポインタでない構造体を埋め込むと、フィールドは自動的にゼロに初期化されます。

+1

これに加えて、nilポインタはJSONにマーシャリングされません。そうでないとあなたは '' location ''で終わるかもしれません: "" ' –

+1

本を読まなかったのですが、' googleGeometry'も同様に ' googleLocation'はうまくいかず、ちょうど私の2cです。 – mkopriva

2

locationnullとなる可能性があります。
このような場合は、ポインタで表すことができます。リテラルの場合は、常にlatlngのデフォルト値が設定されます。
この例に見てみてください。代わりに、参照の値の型を持つWhy pointer?

そして、これを:Value types always have default values

+1

ええ、それは他に何も含まれていない構造体では奇妙に思えますが、JSON出力に表示されなかったフィールドのグループを制御するために*最近*の*埋め込みポインタを持つ構造体を作成しました。おそらく、彼らはこの図書館のどこかでこれをやっているのですが、これは一貫性のためですか?あるいは、たぶん '{}'を時々シリアル化したいと思うかもしれません。 – hobbs

0

私はポインタが内部に埋め込まれているただし際、質問の全体の文脈についてはよく分かりません構造体では、タイプgoogleGeometryの変数が値渡しされても、初期変数と同じメモリアドレスを指しています(アドレスが単純にコピーされるため)。したがって元の構造体は値によって渡されますが、元の変数とコピーされた変数は同じ埋め込みポインタを共有します。それは意図された動作かもしれません。

1

主な理由はJSON(de)シリアル化です。 JSONを構造体にアンマーシャリングして、ポインタを使用して特定の属性がドキュメントに存在するかどうかを検証するのが便利な方法です。 unmarshallerは欠落したフィールドを残すのでnil

次のコードでコードが印刷されます:missing location attribute

func main() { 
    doc := []byte("{}") // json that misses a location member 

    var geometry googleGeometry 
    json.Unmarshal(doc, &geometry) 

    if geometry.googleLocation == nil { 
     fmt.Println("missing location attribute") 
    } else { 
     fmt.Println("location attribute unmarshalled correctly") 
    } 
} 

参照:https://play.golang.org/p/hTj5HvI-AE

関連する問題