本文系第十六篇Golang語言學習教程
指標是一種儲存變數記憶體位址(memory address) 的變數.
如, 變數b
的值為156
,b
在記憶體中的地址是 0x1040a124
, 而變數a
儲存了b
的地址, 我們就稱a
指向了 b
.
指標的聲明
指標變數的類型為 *T
, 該指標指向一個 T
類型的變數. &
用來擷取變數的地址.
例:
package mainimport "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 的值}
以上程式輸出結果為:
type of a is *int
address of b is 0xc420082008
指標的零值
指標的零值是nil
例:
package mainimport "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 mainimport "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 ,相當於改變 b
的值.
輸出為:
type of a is *int
address of b is 0xc420014070
b is 166
new b is 167
向函數傳遞指標參數
package mainimport "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) //函數解引用修改傳入參數 f fmt.Println("val of f after is ", e)}
以上程式中, 首先定義函數change
, 傳入類型為 *int
, 並將傳入參數解引用修改值為66. f 儲存了 e 的地址, 當調用change
參數時, 解引用 f 並改變值為 66.
輸出為:
val of e befor is 77
val of f after is 66
不要向函數傳遞數組的指標, 而應該使用切片
package mainimport "fmt"func modify(arr *[3]int) { (*arr)[0] = 20 //將 arr 解引用, 並將第一個元素賦 20}func main() { a := [3]int{40,50,60} //建立一個數組 a modify(&a) fmt.Println(a)}
在以上程式中, 定義函數modify
, 傳入參數arr
是一個*[3]int
類型的值.
調用函數後, 將 arr 解引用, 並給第一個元素賦值 20.
輸出為:[20 50 60]
a[x] 是 (*a)[x] 的簡寫, 所以以上程式可以寫為:
package mainimport "fmt"func modify(arr *[3]int) { arr[0] = 20 //將 arr 解引用, 並將第一個元素賦 20}func main() { a := [3]int{40,50,60} //建立一個數組 a modify(&a) fmt.Println(a)}
但在 GO 語言中,我們最好用切片來實現以上功能.
package mainimport ( "fmt")func modify(arr []int) { //傳入參數為切片類型 arr[0] = 20}func main() { a := [3]int{40,50,60} //建立一個數組 a modify(a[:]) // 傳入一個切片 fmt.Println(a)}
以上程式中,建立了函數 modify
, 傳入參數為切片類型 .
建立一個切片傳入函數, 函數將切片的第一個元素改為20.
輸出為:[20 50 60]
所以別再傳遞數組指標了,而是使用切片吧。上面的代碼更加簡潔,也更符合 Go 語言的習慣。
最後, GO 並不支援指標運算.
以上為學習Golang 指標篇