指針也是一種類型,也可以建立變量,稱之為指針變量。指針變量的類型為
*Type
,該指針指向一個
Type
類型的變量。指針變量最大的特點就是存儲的某個實際變量的記憶體位址,通過記錄某個變量的位址,進而間接的操作該變量。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cGcq5iM0MDMxU2N2UjM3EjYmZWMzYzX5UzNzETMzEzLclDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.jpg)
7.1 建立指針
建立指針有三種方法。
- 首先定義普通變量,再通過擷取該普通變量的位址建立指針:
// 定義普通變量 x x := "面向加薪學習" // 取普通變量 x 的位址建立指針 p ptr := &x
- 先建立指針并配置設定好記憶體,再給指針指向的記憶體位址寫入對應的值:
// 建立指針 ptr2 := new(string) // 給指針指向的記憶體位址寫入對應的值 *ptr2 = "從0到Go語言微服務架構師" fmt.Println(ptr2) fmt.Println(*ptr2)
- 首先聲明一個指針變量,再從其他變量擷取記憶體位址給指針變量:
// 定義變量 x2 x2 := "Go語言微服務架構師核心22講" // 聲明指針變量 var p *string // 指針初始化 p = &x2 fmt.Println(p)
Tip:
上面舉的建立指針的三種方法對學過 C 語言的人來說可能很簡單,但沒學過指針相關知識的人可能不太明白,特别是上面代碼中出現的指針操作符
&
和
*
。
-
操作符可以從一個變量中取到其記憶體位址。&
-
操作符如果在指派操作值的左邊,指該指針指向的變量;*
操作符如果在指派操作符的右邊,指從一個指針變量中取得變量值,又稱指針的解引用。*
通過下面的例子,你應該就會比較清楚的了解上面兩個指針操作符了。
package main
import "fmt"
func main() {
x := "面向加薪學習"
ptr := &x
fmt.Println("x = ", x) // x = 面向加薪學習
fmt.Println("*ptr = ", *ptr) // *p = 面向加薪學習
fmt.Println("&x = ", &x) // &x = 0x14000010290
fmt.Println("ptr = ", ptr) // p = 0x14000010290
}
7.2 指針的類型
*(指向變量值的資料類型)
就是對應的指針類型。
func pointerType() {
mystr := "Go語言極簡一本通"
myint := 1
mybool := false
myfloat := 3.2
fmt.Printf("type of &mystr is :%T\n", &mystr)
fmt.Printf("type of &myint is :%T\n", &myint)
fmt.Printf("type of &mybool is :%T\n", &mybool)
fmt.Printf("type of &myfloat is :%T\n", &myfloat)
}
func main() {
//...
pointerType()
}
7.3 指針的零值
如果指針聲明後沒有進行初始化,其預設零值是
nil
func zeroPointer() {
x := "從0到Go語言微服務架構師"
var ptr *string
fmt.Println("ptr is ", ptr)
ptr = &x
fmt.Println("ptr is ", ptr)
}
func main() {
//...
zeroPointer()
}
7.4 函數傳遞指針參數
在函數中對指針參數所做的修改,在函數傳回後會儲存相應的修改。
package main
import (
"fmt"
)
func changeByPointer(value *int) {
*value = 200
}
func main() {
x3 := 99
p3 := &x3
fmt.Println("執行changeByPointer函數之前p3是", *p3)
changeByPointer(p3)
fmt.Println("執行changeByPointer函數之後p3是", *p3)
}
7.5 指針與切片
package main
import "fmt"
// 使用切片
func changeSlice(value []int) {
value[0] = 200
}
// 使用數組指針
func changeArray(value *[3]int) {
(*value)[0] = 200
}
func main() {
x := [3]int{10, 20, 30}
changeSlice(x[:])
fmt.Println(x) // [200 20 30]
y := [3]int{100, 200, 300}
changeArray(&y)
fmt.Println(y) // [200 200 300]
}
7.6 Go 中不支援指針運算
package main
func main() {
x := [...]int{20, 30, 40}
p := &x
p++ // error
}