請關注原做者公衆號:Go編程時光程序員
當咱們定義一個變量 nameshell
var name string = "Go指針"
此時,name 是變量名,它只是編程語言中方便程序員編寫和理解代碼的一個標籤。編程
當咱們訪問這個標籤時,計算機會返回給咱們它指向的內存地址裏存儲的值:Go指針
。數組
出於某些須要,咱們會將這個內存地址賦值給另外一個變量名,一般叫作prt(pointer的簡寫),而這個變量,咱們稱之爲指針變量。編程語言
換句話說,指針變量(一個標籤)的值是指針,也就是內存地址。函數
根據變量指向的值,是不是內存地址,把變量分爲兩種:指針
指針建立有三種方法code
第一種方法
內存
先定義對應的變量,再經過變量取得內存地址,建立指針字符串
// 定義普通變量 aint := 1 // 定義指針變量 ptr := &aint
第二種方法
先建立指針,分配好內存後,在給指針指向的內存地址寫入對應的值
// 建立指針 astr := new(string) // 給指針賦值 *astr = "Go指針"
第三種方法
先聲明一個指針變量,再從其餘變量取得內存地址賦值給它
aint := 1 var bint *int // 聲明一個指針 bint = &aint
上面三段代碼中,指針的操做都離不開這兩個符號:
&
:從一個普通變量中取得內存地址*
:當*
在賦值操做值得右邊,從一個指針變量中取得變量值,當*
在賦值操做值得左邊,是指該指針指向的變量經過下面這段代碼,你能夠熟悉這兩個符號的用法
package main import "fmt" func main(){ aint := 1 // 定義普通變量 ptr := &aint // 定義指針變量 fmt.Println("普通變量存儲的是:",aint) fmt.Println("普通變量存儲的是:",*ptr) fmt.Println("指針變量存儲的是:",&aint) fmt.Println("指針變量存儲的是:",ptr) }
輸出以下
普通變量存儲的是:1 普通變量存儲的是:1 指針變量存儲的是:0xc0000100a0 指針變量存儲的是:0xc0000100a0
要想打印指針指向的內存地址,方法有兩種
// 第一種 fmt.Printf("%p",ptr) //第二種 fmt.Println(ptr)
咱們知道字符串的類型是 string,整型是 int,那麼指針如何表示呢?
package main import "fmt" func main() { astr := "hello" aint := 1 abool := false arune := 'a' afloat := 1.2 fmt.Printf("asgr 指針類型是:%T\n", &astr) fmt.Printf("aint 指針類型是:%T\n", &aint) fmt.Printf("abool 指針類型是:%T\n", &abool) fmt.Printf("arune 指針類型是:%T\n", &arune) fmt.Printf("afloat 指針類型是:%T\n", &afloat) }
輸入以下,能夠發現用 *
+ 所指向變量值的數據類型,就是對應的指針類型。
astr 指針類型是:*string aint 指針類型是:*int abool 指針類型是:*bool arune 指針類型是:*int32 afloat 指針類型是:*float
因此若咱們定義一個只接收指針類型的參數的函數,能夠這麼寫
func mytest(ptr *int) { fmt.Println(*ptr) }
當指針聲明後,沒有進行初始化,其零值是 nil。
func main() { a := 25 var b *int // 聲明一個指針 if b == nil { fmt.Println(b) // <nil> b = &a // 初始化:將a的內存地址給b fmt.Println(b) // 0xc0000100a0 } }
切片與指針同樣,都是引用類型。
若是咱們想經過一個函數改變一個數組的值,有兩種方法
儘管兩者均可以實現咱們的目的,可是按照Go語言的使用習慣,建議使用第一種方法,由於第一種方法,寫出來的代碼更簡潔,易懂。
使用切片
func modify(sls []int) { sls[0] = 90 } func main() { a := [3]int{89,90,91} modify(&a) fmt.Println(a) }
使用指針
func modify(arr *[3]int) { (*arr)[0] = 90 } func main() { a := [3]int{89,909,1} modify(&a) fmt.Println(a) }