Go語言中的指針和C/C++ 中的指針用法基本相似。
指針(pointer)在Go語言中可以被拆分爲兩個核心概念:
- 類型指針,允許對這個指針類型的數據進行修改,傳遞數據可以直接使用指針,而無須拷貝數據,類型指針不能進行偏移和運算。
- 切片,由指向起始元素的原始指針、元素數量和容量組成。
受益於這樣的約束和拆分,Go語言的指針類型變量即擁有指針高效訪問的特點,又不會發生指針偏移,從而避免了非法修改關鍵性數據的問題。同時,垃圾回收也比較容易對不會發生偏移的指針進行檢索和回收。
1.認識指針地址和指針類型
一個指針變量可以指向任何一個值的內存地址,它所指向的值的內存地址在 32 和 64 位機器上分別佔用 4 或 8 個字節,佔用字節的大小與所指向的值的大小無關。當一個指針被定義後沒有分配到任何變量時,它的默認值爲 nil。指針變量通常縮寫爲 ptr。每個變量在運行時都擁有一個地址,這個地址代表變量在內存中的位置。Go語言中使用在變量名前面添加&
操作符(前綴)來獲取變量的內存地址(取地址操作),格式如下:
ptr := &v // v 的類型爲 T
取地址操作符&
和取值操作符*
是一對互補操作符,&
取出地址,*
根據地址取出地址指向的值。
package main
import "fmt"
// 交換函數
func swap(a, b *int) {
// 取a指針的值, 賦給臨時變量t
t := *a
// 取b指針的值, 賦給a指針指向的變量
*a = *b
// 將a指針的值賦給b指針指向的變量
*b = t
}
func main() {
// 準備兩個變量, 賦值1和2
x, y := 1, 2
// 交換變量值
swap(&x, &y)
// 輸出變量值
fmt.Println(x, y)
}
//輸出:
//2 1
2.創建指針的另一種方法——new() 函數
Go語言還提供了另外一種方法來創建指針變量,格式如下:
new(類型)
str := new(string)
*str = "Go語言教程"
fmt.Println(*str)
new() 函數可以創建一個對應類型的指針,創建過程會分配內存,被創建的指針指向默認值。