在介紹 Golang 中的指標之前,我們可以先對比一下它和 C 語言中的指標有何不同。這樣有助於理解 Golang 如何優化和簡化指標的使用。
1. 記憶體操作的安全性
2. 指標的零值
3. 垃圾回收
指標(Pointer)是存放變數記憶體地址的變數。在 Golang 中,指標的宣告語法如下:
var p *int
*int
代表這是一個指向int
型態的指標變數。- 當一個指標變數被宣告但未初始化時,它的值為
nil
,表示它還沒有指向任何變數的地址。
在 Golang 中,我們可以通過取地址符號 & 來取得一個變數的記憶體地址,並將這個地址賦值給指標:
var a int = 42 // 宣告一個整數變數 a,並賦值為 42
var p *int = &a // 宣告指標變數 p,並將 a 的地址賦值給它
&a
表示取變數 a
的地址,並將這個地址賦值給指標 p
。
使用範例:
package main
import "fmt"
func main() {
var a int = 42 // 宣告變數 a 並賦值
var p *int // 宣告指標變數 p
p = &a // 將 a 的地址賦值給 p
fmt.Println("a 的值是:", a)
fmt.Println("p 指向的值是:", *p)
*p = 100 // 修改 p 所指向的變數值
fmt.Println("修改後 a 的值是:", a)
}
</* Output: */>
a 的值是: 42
p 指向的值是: 42
修改後 a 的值是: 100
new
函數會分配記憶體空間並返回指向這塊記憶體的指標。使用 new
時,記憶體會自動初始化為該型別的零值(zero value)
。它適合在你不需要立即賦值,只想初始化一個變數並分配指標的情況下使用。
var p *int = new(int) // 分配一個 int 的記憶體並返回指向它的指標
*p = 42 // 為這個指標指向的內存賦值
new(int)
創建了一個 int
型態的變數,並返回該變數的指標,這個變數的初始值為零值 0
。在處理大型數據結構時,指標可以顯著提高性能。傳遞指標而不是值,減少了記憶體的複製,並且能提升執行效率。
func modifySlice(s *[]int) {
for i := range *s {
(*s)[i] *= 2 // 這裡使用指標直接修改 slice 內容
}
}
func main() {
slice := []int{1, 2, 3, 4, 5}
modifySlice(&slice) // 傳遞 slice 的指標
fmt.Println(slice)
}
</* Output: */>
[2, 4, 6, 8, 10]
在這個範例中,
modifySlice
函數透過指標直接修改了slice
的內容。這樣做避免了創建slice
副本,從而減少了記憶體開銷。
在這次的介紹中,我們探討了 Golang 中指標的使用及其與 C 語言的不同之處。Golang 的指標設計更加安全,避免了直接的記憶體操作和指標運算,同時透過自動垃圾回收簡化了記憶體管理。我們學到了如何正確宣告、初始化和操作指標,以及如何使用 new
函數進行動態記憶體分配。此外,透過傳遞指標可以有效提升性能,特別是在處理大型數據結構時。我們還學習了如何避免過度使用指標並正確處理 nil
指標,以確保程式的穩定性和一致性。