Go 指針還能這麼玩?結構體方法調用竟然不用解引用!
Go 語言中的指針詳解
包含字段與方法的簡化寫法
在 Go 語言中,指針是高效操作數據、避免大對象拷貝的重要工具。本文將詳細講解 Go 中指針相關的幾個關鍵概念:
-
&
:取地址 -
*T
:聲明指針類型 -
*p
:解引用指針 -
結構體指針可以使用
ptr.Field
和ptr.Method()
的簡化寫法 -
是否支持多級指針如
**T
一、基本操作符解釋
1. &
:取地址
用於獲取變量的內存地址。
a := 42
p := &a // p 是一個指向 int 的指針
此時 p 類型爲 *int
。
2. *T
:聲明指針類型
var p *int // 聲明一個指向 int 的指針
這裏的 *
表示這是一個指針類型。
3. *p
:解引用指針
fmt.Println(*p) // 輸出 42
*p = 100 // 修改 a 的值爲 100
表示訪問指針所指向的實際值。
二、結構體指針的簡化寫法
Go 提供了兩個非常實用的語法糖:
✅ 1. 字段訪問:ptr.Field
type Person struct {
Name string
}
func main() {
p := Person{Name: "Alice"}
ptr := &p
fmt.Println(ptr.Name) // 合法,等價於 (*ptr).Name
}
Go 編譯器會自動將 ptr.Name
轉換爲 (*ptr).Name
。
✅ 2. 方法調用:ptr.Method()
func (p *Person) SayHello() {
fmt.Println("Hello, ", p.Name)
}
func main() {
p := &Person{Name: "Alice"}
p.SayHello() // 合法,等價於 (*p).SayHello()
}
Go 允許你直接使用指針調用方法,不需要顯式解引用。
這是 Go 特有的設計特性,目的是讓代碼更簡潔、易讀。
三、函數參數傳遞與指針
如果希望函數能修改原始變量,通常需要傳入指針。
func updateValue(v *int) {
*v = 100
}
func main() {
a := 10
updateValue(&a)
fmt.Println(a) // 輸出 100
}
四、是否支持 **T
這樣的多級指針?
Go 支持多級指針,例如:
func main() {
a := 10
p := &a
pp := &p
fmt.Println(**pp) // 輸出 10
**pp = 20
fmt.Println(a) // 輸出 20
}
雖然語法上支持 **T
,但在實際開發中不推薦使用,因爲會增加理解成本和出錯概率。
五、總結對比表
六、最佳實踐建議
-
✅ 使用指針避免大對象拷貝,提高性能。
-
✅ 在函數中修改外部變量時,傳入指針。
-
✅ 對結構體指針使用
ptr.Field
和ptr.Method()
簡化寫法,提升可讀性。 -
⚠️ 避免使用多級指針,除非必要。
-
❌ 不要對非結構體指針使用
.Field
或.Method()
寫法。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/W-Xp0VWFkz4jINQxCFL9qw