最近在教學 Golang 的記憶體處理細節時,重新對 Pointer 和 Pointer Receiver 做了梳理。這兩者經常一起出現,但實際上代表不同層面的設計。
Pointer:一種資料型別
在 Go 裡,指標(Pointer)本質上就是「儲存某個變數記憶體位置的變數」。
var a int = 10幾個重點:
var p *int = &a
p的型別是*int,表示它指向一個int的位址&a是取變數a的位址*p是從記憶體中取出p指向的實際值
這種語法對 C/C++ 開發者來說應該不陌生。Go 的指標語法相對簡潔,不支援指標運算,也不能對記憶體地址做太細的操作。
Pointer Receiver:方法定義時的接收者類型
Go 的 method 語法允許你定義某個類型的方法,在定義時,receiver 可以是值,也可以是指標。
type Counter struct {
value int
}
func (c *Counter) Increment() {
c.value++
}
這裡的 (c *Counter) 表示這是一個「指標接收器」,重點有幾個:
- 如果用值接收器(
c Counter),那就是複製一份;方法裡的修改不會影響外部 - 用指標接收器(
*Counter)的話,修改會作用在原本那個實例上
Go 語言會自動幫你解參考,呼叫方法時不需要寫 (*c).Increment(),直接 c.Increment() 就行,即使 c 是實例不是指標也會自動轉換
自動幫你解參考 => 最最重要的golang特性
使用情境的判斷
如果一個方法會修改 receiver 的內容,應該使用指標接收器。如果不會修改,兩者皆可,但實務上為了一致性,通常會全部都使用 *T。
這一點在標準庫中也能觀察到,例如 bytes.Buffer 的大多數方法就是用 pointer receiver,因為每次操作都會改變狀態。
這不是一個難理解的主題,但常常混淆,也容易在 struct method 設計時留下不一致的選擇。釐清概念後,實務上的判斷與維護也會更直覺。













