天天看點

Go指針,如此輕松掌握,希望有收獲

開篇語

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

指針的了解

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

Go的指針

在Go中指針有兩個概念,一個指針變量是可以指向任何一個值的記憶體位址,指針變量也是占用存儲空間的,在32位系統中占用4個位元組,在64位系統中占用8個位元組,與這個位址存儲的值的大小沒有關系指針類型指針類型和指針變量一塊出現,指的是這個指針變量的類型是什麼,比如我們聲明了一個

tempint=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輸出後一個位址)

如何擷取指針對應的位址的值,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

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

複制