You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中结构体使用&符号的原因及与普通结构体的差异

Differences Between *Vertex (Pointer to Struct) and Vertex (Plain Struct) in Go

Great question! Let's break down the key differences and why you'd choose one over the other, using your example code as context.

Core Differences

  • Memory Handling & Copy Behavior

    • A plain Vertex is a value type: when you assign it to another variable or pass it to a function, Go creates a full copy of the entire struct. So if you do vCopy := v1, vCopy is a separate instance—changes to vCopy.X won't affect v1.X.
    • *Vertex is a pointer type: it stores the memory address of a Vertex instance instead of the struct data itself. Assigning or passing a pointer only copies the address (8 bytes on 64-bit systems), not the whole struct. So pCopy := p means both p and pCopy point to the same underlying Vertex instance.
  • Mutability & Modification

    • To modify a plain struct's fields, you either modify the instance directly, or if it's passed to a function, you have to return the modified struct and reassign it (since the function gets a copy). For example:
      func updateVertex(v Vertex) Vertex {
          v.X = 10
          return v
      }
      // Usage: v1 = updateVertex(v1)
      
    • With a pointer, you can modify the original struct's fields directly through the pointer—no need for copies or return values. Like:
      func updateVertexPtr(v *Vertex) {
          v.X = 10
      }
      // Usage: updateVertexPtr(p) // modifies the original Vertex p points to
      
  • Zero Value Behavior

    • The zero value of a plain Vertex is Vertex{0, 0}—all fields are set to their respective zero values (0 for int here).
    • The zero value of *Vertex is nil—it doesn't point to any valid struct instance. Trying to access fields on a nil pointer (like nil.X) will cause a runtime panic.

Why Use a Pointer Instead of a Plain Struct?

  • Performance for Large Structs
    If your struct has many fields or large data (like a struct with a big slice or string), copying the entire struct every time you pass it around is inefficient. Pointers let you pass just a small address instead, saving memory and CPU cycles.

  • Share & Maintain a Single State
    When multiple parts of your code need to work with the same struct instance (like a configuration object or a shared data structure), pointers ensure all changes apply to the same underlying data. No more dealing with out-of-sync copies.

  • Interface Compliance
    Some interfaces require methods with pointer receivers. For example, if you have an interface:

    type Movable interface {
        Move(dx, dy int)
    }
    

    And you define Move as a pointer receiver:

    func (v *Vertex) Move(dx, dy int) {
        v.X += dx
        v.Y += dy
    }
    

    Only *Vertex types will satisfy the Movable interface—plain Vertex instances won't, because Go doesn't automatically convert value types to pointers for interface implementation.

  • Avoid Accidental Copying
    Sometimes you don't want to create copies by mistake. Using a pointer makes it explicit that you're working with the original instance, which helps prevent bugs where you modify a copy and wonder why the original didn't change.

In your example, p = &Vertex{1, 2} creates a new Vertex instance and immediately takes its address, giving you a pointer to that instance. This is a concise way to create a struct and get a pointer to it in one line.

内容的提问来源于stack exchange,提问作者Tomy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:34:29