自定义结构中的指针

时间:2017-07-28 13:16:33

标签: go

最近,我接触到来自" Go Programming Blueprints" 的书中的以下源代码。

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

我不明白为什么 googleGeometry 结构使用指针而不是文字,这种声明背后的原因是什么?

我希望下面的声明而不是指针。

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

4 个答案:

答案 0 :(得分:2)

我认为这是因为location可能是null或根本不存在。
这种情况可以用指针表示。因为如果它是文字的,您将始终拥有latlng的默认值 请看一下这个例子:Why pointer?

这是一个值类型而不是引用:Value types always have default values

答案 1 :(得分: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

答案 2 :(得分:0)

googleGeometry 嵌入指向googleLocation的指针。它本质上是一个未命名的字段,因此可以访问LatLng字段,就像它们是顶级字段一样。

为什么要使用

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

而不是

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

我认为他们在这里做了错误的电话。指针是可以为零的,所以如果你这样做:

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

你会得到一个零参考恐慌。如果嵌入非指针结构,则字段将自动初始化为零。

答案 3 :(得分:0)

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