GO學習筆記——指針(9)

GO語言也有指針,本質上和C/C++沒有差別,但是在用法上有很多差別,GO語言中的指針是弱化版的C/C++指針。

先來看一段簡單的代碼

func main() {
	a := 1
	b := &a
	fmt.Println(reflect.TypeOf(b),b,*b)
}

執行結果如下

*int 0xc04204e080 1

由此可見:

  • 這個b的類型就是int類型的指針,用*int表示
  • b指向了a,b的值就是a的地址,也就是說a的地址就是0xc04204e080
  • *b就是解引用指針,得到的是a的值,也就是1

基本的用法看起來和C++好像沒有太大的變化,但是還是有幾點是需要注意的。


指針的零值

C/C++中指針可以爲NULL,那麼在GO語言中,空指針就是nil了,這也是我們說的指針的零值(不賦值時候的值)。

GO語言中的指針不能拿來運算

GO語言中的指針是簡單的,弱化版的C/C++指針,就是因爲GO語言規定指針不可以進行運算,而C/C++中的指針可以進行++/--操作,也可以進行+1,+2這樣的運算操作,GO語言簡單就是簡單在它規定了這樣的操作是不合法的,編譯器會自動報錯。

值傳遞配合指針實現引用傳遞

在函數傳參的時候,GO語言只有值傳遞一種方式,沒有引用傳遞

來看下面的代碼

func print(a int){
	fmt.Println(a)
}
func main() {
	a := 1
	print(a)
}

這就是典型的值傳遞,才調用print函數的時候,會拷貝一份變量a,作爲形式參數傳給print函數,調用完print函數之後,這個臨時的拷貝的變量就被銷燬了。這中間有一次拷貝操作,如果這個變量不是int,而是一個自定義類型,且這個類型的大小非常大。那我們如果拷貝了這個變量,肯定就會消耗一定的空間。

這個時候我們就可以使用指針來搞定,同時這也保證了,這次值傳遞傳遞的是變量的地址,而不是整個變量,起到了引用傳遞的效果。

func print(pa *int){
	*pa = 2    //將pa指向的地址的值改爲了2
	fmt.Println(*pa)
}
func main() {
	a := 1
	fmt.Println(a)    //執行print函數之前a是1
	print(&a)
	fmt.Println(a)    //執行print函數之後a是2
}

來看下輸出結果

1
2
2

a的值在調用完print函數以後發生了變化,是因爲print函數體內通過指針改變了原來的值,這個C語言的實現的引用傳遞方式類似。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章