自定义结构中的指针

huangapple go评论101阅读模式
英文:

Pointer within a custom structure

问题

最近,我接触到了《Go编程蓝图》一书中的以下源代码。

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

我不明白的是为什么 googleGeometry 结构体使用指针而不是字面量,并且这样声明的原因是什么?

我原本期望的声明是下面这样的:

type googleGeometry struct {
    gl googleLocation `json:"location"`
}
英文:

Recently, I got exposed to following source code from "Go Programming Blueprints" book.

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

What I don't understand is why googleGeometry structure uses pointer instead of literal, and what is the reason behind such declaration?

I would expect below declaration instead of a pointer.

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

答案1

得分: 2

我猜这是因为location可能为null,或者根本不存在。这种情况可以用指针表示。因为如果是字面值,latlng总是会有默认值。请看这个例子:为什么要用指针?

而这个例子是使用值类型而不是引用类型:值类型总是有默认值

英文:

I suppose it is because location can be null or would be absent at all.
Such cases can be represented with pointers. Because if it would be literal you will always have default values for lat and lng.
Please take a look on this example: Why pointer?

And this with a value type instead of reference: Value types always have default values

答案2

得分: 1

主要原因是JSON(反)序列化。如果您想将JSON解组为结构体,并验证文档中是否存在某些属性,使用指针是一种方便的方式。由于解组器将缺失的字段设置为nil,因此可以方便地验证缺失的字段。

以下代码将打印:missing location attribute

func main() {
    doc := []byte("{}") // 缺少 location 成员的 JSON

    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

英文:

The main reason is JSON (de)serialization. If you want to unmarshal JSON into a struct and validate if certain attributes are present in the document using a pointer is a convenient way. Since the unmarshaller will leave missing fields nil.

The following code code will print: 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")
    }
}

See: https://play.golang.org/p/hTj5HvI-AE

答案3

得分: 0

googleGeometry嵌入了一个指向googleLocation的指针。它本质上是一个无名字段,这样LatLng字段就可以像顶级字段一样访问。

为什么要使用

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

而不是

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

我认为他们在这里做出了错误的决定。指针是可空的,所以如果你这样做:

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

你将会得到一个空引用恐慌。如果嵌入一个非指针结构体,字段将自动初始化为零值。

英文:

googleGeometry embeds a pointer to a googleLocation. It is essentially an unnamed field so that the Lat and Lng fields are accessible as if they were top level fields.

Why use

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

instead of

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

?

I think they made the wrong call here. The pointer is nillable so if you do:

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

you will get a nil reference panic. If you embed a non-pointer struct, the fields will be automatically initialized to zeros.

答案4

得分: 0

我不确定整个问题的上下文,但是当一个指针嵌入在结构体中时,即使以值传递的方式传递类型为googleGeometry的变量,嵌入的googleLocation指针仍然指向与初始变量相同的内存地址(因为地址只是被复制了)。因此,尽管原始结构体是按值传递的,但原始变量和复制的变量仍共享相同的嵌入指针。这可能是预期的行为。

英文:

I'm not sure about the entire context of the question, however when a pointer is embedded inside the struct, even when the variable of type googleGeometry is passed by value the embedded googleLocation pointer still points to the same memory address as the initial variable (as the address is simply copied). Therefore although the original struct is passed by value both original and the copied variables share the same embedded pointer. That might be the intended behaviour.

huangapple
  • 本文由 发表于 2017年7月28日 21:16:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/45374548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定