Go中的指針

學Java以來,讓程序員忽略了指針和內存地址這些概念,Java幫我們封裝了對象,簡化了對象引用之間的關係。在Go語言中,又幫我們回憶起這些概念。

我們創建的每一個對象在內存中都有一個位置去存儲,每個內存塊都有一個地址表示當前位置,通常用十六進制表示,如0x24005676543。Go語言取地址的符號是&。放在一個變量前使用就會返回相應變量的內存地址。

比如下面的代碼:

var a = 3
fmt.Printf("num is : %d, it's location in memory: %p\n", a, &a)
輸出:

num is : 3, it's location in memory: 0xc000062080

可以看到&a輸出了a的內存地址。

你可以將&a賦值給一個變量,然後觀察這個變量的類型,使用reflect.TypeOf()方法:

var a = 3
intP = &a
b := &a
fmt.Println(reflect.TypeOf(b))

輸出:
*int

可以看到&a的返回類型是 *int。

我們可以將一個變量的內存地址放在一個叫做指針的特殊數據類型中,聲明一個指針的方式如下:

var p *int

然後我們可以使用p去指向一個內存地址:

p = &a

那麼我們如何通過指針來獲取對應內存地址的值呢,這也是有辦法的。你可以在指針類型前面加上 * 號(前綴)來獲取指針所指向的內容,這裏的 * 號是一個類型更改器。使用一個指針引用一個值被稱爲間接引用。

var p *int
var a = 3
p = &a
fmt.Println(*p)

*p打印的是a的值。

當一個指針被定義沒有分配任何變量的時候,它的值爲nil。

對於任何一個變量val,如下表達式都是正確的:

var == *(&var)

有如下你需要注意的是,你不能獲取到一個常量或者一個沒有賦值操作的文字的內存地址:

const PI  = 3.14
piP := &PI Cannot take the address of 'PI'
p2 := &3 Cannot take the address of '3'

在c語言中,指針是可以由程序員自行控制移動位置的,這無疑給程序增加了很多的不確定性,在Go中指針的概念其實更相當於是Java中的引用。它比Java中的引用高級之處在於:

Java中的參數傳遞,傳遞的是值的拷貝,但是在Go中你可以使用指針來傳遞這個值,它直接指向了這個值的內存地址,並且只佔用了4個或者8個字節。

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