【GoLang 那點事】Go 指標,如此輕鬆掌握,希望有收穫

a_wei發表於2019-08-14

開篇語

依稀記得大學必修課,C語言中的指標,簡直是噩夢,指來指去,有沒有暈乎乎的感覺,我在想是不是也因為如此,所以Java語言的開發者C才比C語言的多,Java正因為解決了C的痛點,所以今天才能變成語言排行榜佔其首,Go作為後起之秀,又引入這麼複雜難懂的概念,可見指標我們還是需要學習的,下面我們一起體驗一下go的指標吧

指標的理解

  • 我的理解指標(Point),一個變數指向記憶體中儲存某個值的地址,那麼這個變數是一個指標變數,個人是如此理解的,也就是說指標指的是地址,而不是值
  • 百度百科的定義,指標(Pointer)是程式語言中的一個物件,利用地址,它的值直接指向存在電腦儲存器中另一個地方的值。由於通過地址能找到所需的變數單元,可以說,地址指向該變數單元。因此,將地址形象化的稱為“指標”。意思是通過它能找到以它為地址的記憶體單元。

Go的指標

在Go中指標有兩個概念,一個指標變數是可以指向任何一個值的記憶體地址,指標變數也是佔用儲存空間的,在32位系統中佔用4個位元組,在64位系統中佔用8個位元組,與這個地址儲存的值的大小沒有關係指標型別指標型別和指標變數一塊出現,指的是這個指標變數的型別是什麼,比如我們宣告瞭一個temp int = 1,那麼temp變數的這個型別是 int,同時指標變數也是有指標型別的,用 T表示,T是type的意思,代表具體的型別,比如 `pointTemp int  = &temp, 代表 pointTemp這個變數是指標變數,型別是*int`我們看下面一段程式碼

func PointStudy()  {   
    // 每一個變數在執行時都有一個地址(這個地址儲存著這個變數對應的值)  
    var temp int = 1   
    //  go語言的取地址符, temp 變數,通過&符號來獲取temp這個變數在記憶體中的地址,我們將獲取到的地址賦值給一個指標變數 pointTemp ,型別*int   
    var pointTemp *int= &temp
   fmt.Println(temp)   
   fmt.Println(pointTemp)
}
//輸出結果
1
0xc00005a2d0

指標變數也是變數,變數、指標和地址三者的關係是:每一個變數都有自己地址,每一個指標的值就是地址(也就是這個指標通過fmt.Println輸出後一個地址)

【GoLang 那點事】Go 指標,如此輕鬆掌握,希望有收穫

如何獲取指標對應的地址的值,go語言中通過 &符號 獲取變數地址,通過 * 來獲取地址儲存的值

func PointStudy()  {   
// 每一個變數在執行時都有一個地址(這個地址儲存著這個變數對應的值)   
var temp int = 1   
// go語言獲取地址符, temp 變數,通過&符號來獲取temp這個變數在記憶體中的地址,我們將獲取到的地址賦值給一個指標變數 pointTemp ,型別為 *int   
var pointTemp *int =temp   
fmt.Println(pointTemp)   
fmt.Println(*pointTemp)}
//輸出結果0xc00005a2d01
// 思考一下這行程式碼輸出什麼
fmt.Println(*&temp)

值傳遞和指標傳遞

值傳遞和指標傳遞go語言函式呼叫時有兩種傳遞方式一種是值傳遞

  • 一種是值傳遞,看如下程式碼
func ValueTransmit(){  
    temp := 1   
    fmt.Println(";value transmit before:",temp)  
    method1(temp)   
    fmt.Println("value transmit after:",temp)
}
func method1(temp int)  {  
    fmt.Println("method before:",temp)  
    temp = 2   
    fmt.Println("method after;",temp)
}
//結果
value transmit before: 1
method1 before: 1
method1 after 2
value transmit after: 1
//從上邊程式碼可以看出值傳遞是一種copy的方式,temp從ValueTransmit傳遞到method1(),是把temp重新copy了一份,methd1中修改temp是不會影響ValueTransmit中的temp
  • 一種是指標傳遞,看如下程式碼:
func PointTransmit(){   
    var temp = 1  
    fmt.Println("point transmit before:",temp)   
    method2(&temp)  
    fmt.Println("point transmit after",temp)
}
func method2(temp *int)  {  
    fmt.Println("method2 before:",*temp)  
    *temp = 2  
    fmt.Println("method2 after:",*temp)
}
//結果
point transmit before: 1
method2 before: 1
method2 after 2
point transmit after: 2

//從上面的程式碼中可以看出指標傳遞後, 對指標所指向地址的值修改後,對其它方法是可見的

歡迎大家關注微信公眾號:“golang那點事”,更多精彩期待你的到來

【GoLang 那點事】Go 指標,如此輕鬆掌握,希望有收穫

那小子阿偉

相關文章