Golang入门教程(十五)指针
什么是指針?
指針是一個變量,用于存儲另一個變量的內存地址。
在上面的例子中,變量b的值是156,存儲在內存地址0x1040a124。 變量a包含b的地址。 可以說現在a指向b。
聲明指針
指向類型?T?的指針用?*T?表示
讓我們寫一些代碼。
package mainimport ( "fmt" )func main() { b := 255var a *int = &bfmt.Printf("Type of a is %T\n", a)fmt.Println("address of b is", a) }&運算符用于獲取變量的地址。 在上面的程序中,我們將b的地址賦給一個類型為* int的類型。 據說現在a指向b。 當我們在a中打印該值時,b的地址將被打印。 這個程序輸出
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_01.go" Type of a is *int address of b is 0xc042054080你可能會得到一個不同的b地址,因為b的位置可以在內存中的任何地方。執行兩次得到的結果
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_01.go" Type of a is *int address of b is 0xc042054080[Done] exited with code=0 in 11.167 seconds[Running] go run "d:\GoProject\src\golang-study-line\basic-02\tempCodeRunnerFile.go" Type of a is *int address of b is 0xc04200e098[Done] exited with code=0 in 0.954 seconds?空指針
指針的零值為 nil。
package mainimport ( "fmt" )func main() { a := 25var b *intif b == nil {fmt.Println("b is", b)b = &afmt.Println("b after initialization is", b)} }b在上面的程序中最初是 nil,然后它被分配到a的地址。 這個程序輸出(同樣是執行兩次):
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_02.go" b is <nil> b after initialization is 0xc042054080[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_02.go" b is <nil> b after initialization is 0xc042054080如何引用一個指針
如何引用指針意味著訪問指針指向的變量的值。 * a是尊重a的語法。
讓我們看看這是如何在程序中起作用的。
package main import ( "fmt" )func main() { b := 255a := &bfmt.Println("address of b is", a)fmt.Println("value of b is", *a) }在上述程序的第10行中,我們引用并打印它的值。 如預期的那樣,它打印出b的值。 該程序的輸出是
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_03.go" address of b is 0xc042054080 value of b is 255讓我們寫一個更多的程序,我們使用指針改變b中的值。
package mainimport ( "fmt" )func main() { b := 255a := &bfmt.Println("address of b is", a)fmt.Println("value of b is", *a)*a++fmt.Println("new value of b is", b) }在上面的程序中,我們將a指向的值增加1,這將b的值從a改變為b。 因此b的值變成256.程序的輸出是
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_04.go" address of b is 0xc04200e098 value of b is 255 new value of b is 256將指針傳遞給一個函數
package mainimport ( "fmt" )func change(val *int) { *val = 55 }func main() { a := 58fmt.Println("value of a before function call is",a)b := &achange(b)fmt.Println("value of a after function call is", a) }在上面的程序中,在第4行號。 我們將指針變量b傳遞給函數改變。 內部轉換函數中,使用第8行中的解除引用來更改a的值。該程序輸出,
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_05.go" value of a before function call is 58 value of a after function call is 55不要將指向數組的指針作為參數傳遞給函數。 改用切片。
讓我們假設我們想對函數內的數組進行一些修改,并且調用者應該可以看到函數內對該數組所做的更改。 這樣做的一種方式是將指向數組的指針作為函數的參數。
?在上面的程序中的第3行號,我們將數組a的地址傳遞給修改函數。 在修改函數的第8行中,我們取消引用arr并將90分配給數組的第一個元素。 這個程序輸出
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\tempCodeRunnerFile.go" [90 90 91]a [x]是(* a)[x]的簡寫。 所以上述程序中的(* arr)[0]可以用arr [0]代替。
讓我們用這種簡寫語法重寫上述程序。
package mainimport ( "fmt" )func modify(arr *[3]int) { arr[0] = 90 }func main() { a := [3]int{89, 90, 91}modify(&a)fmt.Println(a) }這個程序也輸出
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_07.go" [90 90 91]雖然這種將指向數組的指針作為參數傳遞給函數并對其進行修改的方式很有效,但這并不是在Go中實現此功能的慣用方式。 我們可以使用切片。
讓我們用切片重寫相同的程序。
package mainimport ( "fmt" )func modify(sls []int) { sls[0] = 90 }func main() { a := [3]int{89, 90, 91}modify(a[:])fmt.Println(a) }在上述程序的第13行中,我們將一個切片傳遞給修改函數。 切片的第一個元素在修改函數中更改為90。
這個程序輸出
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_08.go" [90 90 91]所以避免傳遞指向數組的指針,使用切片代替它。 這段代碼更干凈并且是慣用的Go
Go不支持指針算術
Go不支持C語言等其他語言中的指針運算。
上面的程序會拋出編譯錯誤
[Running] go run "d:\GoProject\src\golang-study-line\basic-02\basic_pointer_09.go" # command-line-arguments basic-02\basic_pointer_09.go:6:6: invalid operation: p++ (non-numeric type *[3]int)?
參考:
https://golangbot.com/pointers/
總結
以上是生活随笔為你收集整理的Golang入门教程(十五)指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql开局配置
- 下一篇: 3月16日学习内容整理:metaclas