本文系第十六篇Golang語言學(xué)習(xí)教程
指針是一種存儲變量內(nèi)存地址(memory address) 的變量.
如上圖, 變量b
的值為156
,b
在內(nèi)存中的地址是 0x1040a124
, 而變量a
存儲了b
的地址, 我們就稱a
指向了 b
.
指針的聲明
指針變量的類型為 *T
, 該指針指向一個 T
類型的變量. &
用來獲取變量的地址.
例:
package main
import "fmt"
func main() {
b := 166 //定義變量 b
var a *int = &b //b 的地址賦給 a, 或說 a 指向 b
fmt.Printf("type of a is %T\n", a) //打印 a 的類型
fmt.Println("address of b is ", a) //打印 a 的值
}
以上程序輸出結(jié)果為:
type of a is *int
address of b is 0xc420082008
指針的零值
指針的零值是nil
例:
package main
import "fmt"
func main() {
c := 358
var d *int //d 初始化為 nil
if d == nil {
fmt.Println("b is ",d)
d = &c // 給 d 賦值 c 的地址
fmt.Println("after init b is ", d)
}
}
以上程序中,可以看到 b 的初始值為 nil.
輸出為:
b is <nil>
after init b is 0xc42008e030
指針的解引用
指針的接引用可以獲取指針指向變量的值, 將 a
解引用的語法是 *a
.
例:
package main
import "fmt"
func main() {
b := 166 //定義變量 b
var a *int = &b //b 的地址賦給 a, 或說 a 指向 b
fmt.Printf("type of a is %T\n", a) //打印 a 的類型
fmt.Println("address of b is ", a) //打印 a 的值
fmt.Println("b is ", *a) // 解引用 a
*a++ //給 *a +1 ,等于給 b + 1
fmt.Println("new b is ", b)
}
以上程序中, 首先接引用*a
, 返回 b
的值. 然后給 *a
+1 ,相當(dāng)于改變 b
的值.
輸出為:
type of a is *int
address of b is 0xc420014070
b is 166
new b is 167
向函數(shù)傳遞指針參數(shù)
package main
import "fmt"
func change(val *int) {
*val = 66
}
func main() {
e := 77
fmt.Println("val of e befor is ", e)
f := &e // f 等于 e 的地址
change(f) //函數(shù)解引用修改傳入?yún)?shù) f
fmt.Println("val of f after is ", e)
}
以上程序中, 首先定義函數(shù)change
, 傳入類型為 *int
, 并將傳入?yún)?shù)解引用修改值為66. f 存儲了 e 的地址, 當(dāng)調(diào)用change
參數(shù)時, 解引用 f 并改變值為 66.
輸出為:
val of e befor is 77
val of f after is 66
不要向函數(shù)傳遞數(shù)組的指針, 而應(yīng)該使用切片
package main
import "fmt"
func modify(arr *[3]int) {
(*arr)[0] = 20 //將 arr 解引用, 并將第一個元素賦 20
}
func main() {
a := [3]int{40,50,60} //創(chuàng)建一個數(shù)組 a
modify(&a)
fmt.Println(a)
}
在以上程序中, 定義函數(shù)modify
, 傳入?yún)?shù)arr
是一個*[3]int
類型的值.
調(diào)用函數(shù)后, 將 arr 解引用, 并給第一個元素賦值 20.
輸出為:[20 50 60]
a[x] 是 (*a)[x] 的簡寫, 所以以上程序可以寫為:
package main
import "fmt"
func modify(arr *[3]int) {
arr[0] = 20 //將 arr 解引用, 并將第一個元素賦 20
}
func main() {
a := [3]int{40,50,60} //創(chuàng)建一個數(shù)組 a
modify(&a)
fmt.Println(a)
}
但在 GO 語言中,我們最好用切片來實現(xiàn)以上功能.
package main
import (
"fmt"
)
func modify(arr []int) { //傳入?yún)?shù)為切片類型
arr[0] = 20
}
func main() {
a := [3]int{40,50,60} //創(chuàng)建一個數(shù)組 a
modify(a[:]) // 傳入一個切片
fmt.Println(a)
}
以上程序中,創(chuàng)建了函數(shù) modify
, 傳入?yún)?shù)為切片類型 .
創(chuàng)建一個切片傳入函數(shù), 函數(shù)將切片的第一個元素改為20.
輸出為:[20 50 60]
所以別再傳遞數(shù)組指針了碍现,而是使用切片吧颊艳。上面的代碼更加簡潔瑰排,也更符合 Go 語言的習(xí)慣。
最后, GO 并不支持指針運算.
以上為學(xué)習(xí)Golang 指針篇