代码之家  ›  专栏  ›  技术社区  ›  AntoineB

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

  •  2
  • AntoineB  · 技术社区  · 7 年前

    我一直在跟随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 回复  |  直到 7 年前
        1
  •  4
  •   peterSO    7 年前

    这是一个非常常见的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}
    

    这也是隐藏未报告(私有)的一个非常常见的习惯用法 结构 领域。

    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 效率更高。如果要更改 结构 论点

        2
  •  0
  •   enocom bruno conde    7 年前

    思考这两种初始化方式的另一种方式(例如。, 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)