什麼是指標
寫程式碼的時候,我們通過變數就可以操作儲存在記憶體中的值,進行賦值、加減運算等。大家有沒有想過,變數代表什麼呢?其實,一個變數對應一段記憶體空間,這段空間就儲存了該變數相對應型別的值。指標的值就對應變數的地址,只通過指標,就可以更新或者讀取變數的值,而不需要用到變數名。
var i int = 10 //宣告變數i,並初始化為10
var ptr *int = &i
fmt.Println(ptr,*ptr)
// 0xc000018060 10 指標變數ptr儲存的是i地址,*ptr對應指標指向的變數的值
*ptr = 12 // i=12 更新指標指向的變數的值
fmt.Println(*ptr,i) // 12 12
複製程式碼
上面這段程式碼,宣告瞭*int
型別的指標變數 ptr
,通過取址運算子&
獲得指向整型變數 i
的地址。可以說,指標ptr
指向變數i
,或者說ptr
指標儲存了變數i
的地址。
指標宣告
通過上面一段話的解釋,相信大家對指標有了比較清晰的認識:指標指向一個變數的記憶體地址。要想使用指標,必須先宣告,格式如下:
var var_name *var_type
// var_name 指標名稱,var_type 指標所指向的變數的型別
複製程式碼
var i int = 10
str := "go"
var ip *int // *int型別的指標
var pstr *string // *string型別的指標
ip = &i
pstr = &str
fmt.Println(*ip,*pstr) // 10 go
複製程式碼
注意:*int
型別的指標,說明該指標指向的一定是int
型別的變數,*string
型別也類似。
str := "go"
var ip *int
ip = &str // 編譯不會通過
複製程式碼
*int
型別的指標,指向的變數若是string
型別的,編譯器編譯的時候就會報錯:
cannot use &str (type *string) as type *int in assignment
複製程式碼
如何使用指標
文章寫到這裡,關於如何使用指標,其實上文已經列出來了,主要經過三個步驟:宣告、賦值和訪問指標指向的變數的值
x,y := 1,"go"
var px *int = &x // 1、宣告並初始化
var py = &y // 2、省略指標型別,編譯器自動判斷
//px,py := &x,&y // 3、使用 :=
fmt.Println(*px,*py) // 1 go 訪問
複製程式碼
關於空指標
一個指標已宣告而沒有賦值時,稱為空指標,為 nil
。任何型別的指標的零值都是 nil
。
var ip *int
fmt.Println(ip) // nil
fmt.Printf("ip 的值為:%x", ip) // ip 的值為:0
複製程式碼
如果ip != nil
為真,那麼p是指向某個有效變數。指標之間也是可以進行相等測試的,只有當它們指向同一個變數或全部是nil
時才相等。
1、指向同一個變數 true
x,_ := 1,1
px,py := &x,&x
fmt.Println(px == py)
2、指向不同變數 false
x,y := 1,1
px,py := &x,&y
fmt.Println(px == py)
3、兩個nil指標 true
var px *int
var py *int
fmt.Println(px == py)
複製程式碼
指標作為函式引數使用
指標包含的是一個變數的地址,如果將一個指標作為引數傳遞給函式,就可以通過指標來更新變數的值。
func a(p *int){
*p++
}
i := 10
fmt.Println(i) // 10
a(&i);
fmt.Println(i) // 11
複製程式碼
不常用的new函式
給大家介紹下new
函式,內建的new
函式也是一種建立變數的方法,new(type)
表示建立一個type
型別的匿名變數,並初始化為type
型別的零值,返回變數的地址,指標型別為*type
。
p := new(int) // p, *int 型別, 指向匿名的 int 變數
fmt.Println(*p) // 0
*p = 2 // 設定 int 匿名變數的值為 2
fmt.Println(*p) // 2
複製程式碼
用new
函式建立變數和普通變數宣告語句方式建立變數沒有什麼區別,除了不需要宣告一個臨時變數的名字外。
下面的兩個函式有著相同的行為:建立變數,並返回變數地址
func newA() *int {
return new(int)
}
func newB() *int {
var i int
return &i
}
複製程式碼
每次呼叫new
函式都會返回新的變數的地址:
p := new(int)
q := new(int)
fmt.Println(p,q) // 0xc000018060 0xc000018068
複製程式碼
new
函式使用的比較少,不過覺得挺有意思的,就在這給大家分享下!實際程式設計,多的還是使用具體型別建立變數,畢竟更方便,是吧!
(全文完)
原創文章,若需轉載請註明出處!
歡迎掃碼關注公眾號「Golang來啦」或者移步 seekload.net ,檢視更多精彩文章。
公眾號「Golang來啦」給你準備了一份神祕學習大禮包,後臺回覆【電子書】領取!