1. 程式人生 > >【Golang 基礎】Go 語言的指標

【Golang 基礎】Go 語言的指標

Go 語言的指標

  變數是一種使用方便的佔位符,用於引用計算機地址,而在 Go 語言中可以通過 &符號獲取一個變數在計算機中對應的記憶體地址。

package basic

import "fmt"

func main(){
	a := 1
	fmt.Println(&a) // 0xc4200180a0
}

  一個指標變數指向了一個值的記憶體地址。Go 語言中的指標語法與 C++ 類似,都是使用 *符號宣告指標變數;

package basic

import "fmt"

func main(){
	a := 1
	var p *int = &a
	
	fmt.Printf
("獲取變數記憶體地址 %x\n", p) // 獲取變數記憶體地址 c4200180a0 fmt.Printf("獲取指標變數值 %v", *p) // 獲取指標變數值 1 }

Go 語言雖然有指標,但是沒有指標算數,不能對其進行加減,但可以把指標值賦給另一個指標。這也就是 Golang 中的指標與 C++ 中指標的最大區別

可以通過將 unsafe.Pointer轉換為 uintptr,然後做變相指標運算。 uintptr可以轉換為整數。

值傳遞?引用傳遞?

  在學習引用型別語言時,我們首先要搞清楚,當給一個函式/方法傳參的時候,使用的是指傳遞還是引用傳遞。實際上,大部分引用型別語言,引數為基本型別時,使用的是值傳遞。也就是另外複製了一份引數到當前的函式呼叫棧。引數為高階型別時,使用的是引用傳遞。這個主要是因為虛擬機器的記憶體管理導致的。

  記憶體管理中的記憶體區域一般包括 堆(heap) 和 棧(stack) 主要用來儲存當前呼叫棧用到的簡單資料型別:string、boolean、int、float 等。這些型別的記憶體佔用小,容易回收,基本上它們的值和指標佔用的空間差不多,因此可以直接複製,GC 也比較容易做針對性的優化。複雜的高階型別佔用的記憶體往往相對較大,儲存在 堆(heap) 中,GC回收率相對較低,代價也較大,因此傳 引用/指標 可以避免進行成本較高的複製操作,並且節省記憶體,提高程式執行效率。

  因此,在以下情況下可以考慮使用指標:

  1. 需要改變引數的值;
  2. 避免複製操作;
  3. 節省記憶體;

而在 Golang 中,具體到高階型別 struct,slice,map 也各有不同。實際上,只有 struct 的使用有點複雜,slice,map,chan 都可以直接使用,不用考慮是值還是指標。