Go - 什么时候“& MyStruct {1,2}”语法实例化一个结构并获得指向它的指针是有用的?

时间:2018-02-03 21:03:37

标签: go struct

我一直在浏览Go编程语言以熟悉该语言,该语言的一个特点让我感到疑惑。

在关于Struct Literals的步骤中,他们解释了您可以通过多种方式实例化结构:

type Vertex struct {
    X, Y int
}

var (
    v1 = Vertex{1, 2}  // has type Vertex
    v2 = Vertex{X: 1}  // Y:0 is implicit
    v3 = Vertex{}      // X:0 and Y:0
    p  = &Vertex{1, 2} // has type *Vertex
)

我理解三种第一种方式是如何工作以及它们何时有用是没有问题的,但我无法弄清楚最后一种解决方案p = &Vertex{1, 2}的任何用例。

实际上,我无法想到任何情况下必须实例化*Vertex,而不必在代码中使用Vertex类型的变量:

func modifyingVertexes(myVertex *Vertex) {
    myVertex.X = 42;
}

func main() {
    myVertex := Vertex{1, 2}

    modifyingVertexes(&myVertex)

    fmt.Println(myVertex.X)
}

如果可能的话,我可以看到一个用途:

func modifyingVertexes(myVertex *Vertex) {
    myVertex.X = 42;
}

func main() {
    modifyingVertexes(&Vertex{1, 2})

    fmt.Println(???.X) // Accessing the vertex initialized in the modifyingVertexes func call
}

但由于我认为不可能,我真的不知道如何使用它?

谢谢!

2 个答案:

答案 0 :(得分:4)

这是一个非常常见的Go习语,返回初始化struct变量的地址。

package main

import "fmt"

type Vertex struct {
    X, Y int
}

func NewVertex(x, y int) *Vertex {
    return &Vertex{X: x, Y: y}
}

func main() {
    v := NewVertex(1, 2)
    fmt.Println(*v)
}

游乐场:https://play.golang.org/p/UGOk7TbjC2a

输出:

{1 2}

这也是隐藏未导出(私人)struct字段的常用习惯。

package main

import "fmt"

type Vertex struct {
    x, y int
}

func NewVertex(x, y int) *Vertex {
    return &Vertex{x: x, y: y}
}

func (v *Vertex) Clone() *Vertex {
    return &Vertex{x: v.x, y: v.y}
}

func main() {
    v := NewVertex(1, 2)
    fmt.Println(*v)

    w := v.Clone()
    fmt.Println(*w)
}

游乐场:https://play.golang.org/p/ScIqOIaYGPn

输出:

{1 2}
{1 2}

在Go中,所有参数都按值传递。使用大structs指针更有效。如果您希望更改struct参数的值,则还需要指针。

答案 1 :(得分:0)

考虑两种初始化方式(例如foo{}&foo{})的另一种方法是通过您希望实现的目标。如果你需要一个永远不会改变的值对象,那么foo{}就可以了。另一方面,如果您需要稍后更改对象,则最好使用引用。例如:

// using a value object because it will never change
oneHundredDollars := Cash{Amount: 100, Currency: "Dollars"}

// using a reference because the account's balance will change.
a := &Account{Balance: 0}

// changes Balance
a.Deposit(oneHundredDollars)