Go起步:5、複合類型2--指標(pointer)、結構體(struct)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

之前關於Go的複合類型聊到數組和切片,今天繼續看看指標(pointer)和結構體(struct)。

指標(pointer)

取地址符–&

Go具有指標。指標儲存了變數的記憶體位址。
我們都知道,變數是一種使用方便的預留位置,用於引用電腦記憶體位址。
這裡先要說下Go語言的取地址符– &,放到一個變數前使用就會返回相應變數的記憶體位址。

package mainimport "fmt"func main() {    var a int = 20    var s string = "a"    fmt.Printf("a 變數的儲存地址: %x\n", &a)    fmt.Printf("s 變數的儲存地址: %x\n", &s)}

%x是十六進位輸出。

可以看出,兩次啟動並執行結果中,int型的變數地址不同的,string型的變數地址是相同的,這點是不是和java一樣呢?–int是實值型別,string是參考型別。

指標的定義

類型 *T 是指向 T 類型值的指標。其零值為 nil 。

var p *int

以上定義了一個int類型的指標。
& 操作符會產生一個指向其運算元的指標。
* 操作符表示指標指向的底層值。

package mainimport "fmt"func main() {    var p *int //定義一個指標變數    fmt.Printf("p 變數的初始儲存地址: %x\n", p)    i := 10    p = &i //將指標指向變數i    fmt.Printf("p 變數的儲存地址: %x\n", p)    /* 使用指標訪問值 */    fmt.Printf("*p 變數的值: %d\n", *p)    fmt.Printf("i 變數的值: %d\n", i)    *p = 20 //通過指標 p 設定 i    fmt.Printf("p 變數的儲存地址: %x\n", p)    /* 使用指標訪問值 */    fmt.Printf("*p 變數的值: %d\n", *p)    fmt.Printf("i 變數的值: %d\n", i)}


可以看出,

  • 指正定義是預設的地址是0,這時它的值就是nil。
  • 當指標指向變數i時,它的地址就變成了變數i的地址,通過&操作符完成,這時他的值就是變數i的值。
  • 當通過操作符*改變指標的值時,對應的i的值也發生了變化,以為他們引用的是同一個地址上的值。
    這也就是通常所說的“間接引用”或“重新導向”。
    總結一下,使用指標需要三步,首先,定義指標變數。然後,為指標變數賦值(&)。最後就可以訪問指標變數中指向地址的值(*)。

指標的指標

如果一個指標變數存放的又是另一個指標變數的地址,則稱這個指標變數為指向指標的指標變數。當定義一個指向指標的指標變數時,第一個指標存放第二個指標的地址,第二個指標存放變數的地址。

聲明格式如下:

var ptr **int;

以上指向指標的指標變數為整型。

package mainimport "fmt"func main() {    var a int    var ptr *int    var pptr **int    a = 10    /* 指標 ptr 地址 */    ptr = &a    /* 指向指標 ptr 地址 */    pptr = &ptr    /* 擷取 pptr 的值 */    fmt.Printf("變數 a = %d\n", a)    fmt.Printf("變數 a 記憶體位址 %x\n", &a)    fmt.Printf("指標變數 *ptr = %d\n", *ptr)    fmt.Printf("指標變數 *ptr 記憶體位址 %x\n", &*ptr)    fmt.Printf("指向指標的指標變數 **pptr = %d\n", **pptr)    fmt.Printf("指向指標的指標變數 **pptr 記憶體位址 %x\n", &**pptr)}


可以看出,變數a,ptr,pptr都指向了同一個地址。實際上他們引用的是同一個記憶體位址,所以他們的值也都是一樣的。
總之,指標在Go中的用途還是很廣泛的,大部分同C語言的也有些共通指出,但與 C 不同,Go 沒有指標運算。

結構體(struct)

結構體( struct )就是由一系列具有相同類型或不同類型的資料構成的欄位集合。在結構體中可以為不同項定義不同的資料類型。

定義和初始化

struct關鍵之用於定義結構體,type 聲明就是定義的類型。

type T struct {    name string // name of the object    value int // its value}

如下的代碼:

package mainimport "fmt"type Vertex struct {    X int    Y string}func main() {    var v = Vertex{1, "s"}    fmt.Println(v)    fmt.Println(v.X)    fmt.Println(v.Y)    v.X = 10    fmt.Println(v.X)}


上面的代碼定義了一個名為Vertex的結構體,結構體是由int和string兩個資料類型構成。
然後在main函數中定義了一個類型為Vertex的變數。通過上面的程式也可以得出,操作一個結構體的內容直接通過.操作符就可以了,不管是取值還是賦值。

結構體指標

結構體指標就是指向結構體的指標,類似於其他指標變數。定義結構體指標,結構體的欄位就可以通過結構體指標來訪問。
特殊的首碼 & 返回一個指向結構體的指標。
如果我們有一個指向結構體的指標 p ,那麼可以通過 (*p).X 來訪問其欄位 X 。 不過這麼寫太囉嗦了,所以語言也允許我們使用隱式間接引用,直接寫 p.X 就可以。

package mainimport "fmt"type Vertex struct {    X int    Y string}func main() {    v := Vertex{1, "2"}    p := &v    p.X = 333333333    fmt.Println(v)    fmt.Println(p.X)    fmt.Println((*p).X)}


可以看出,定義的指向結構體v的指標p,對於p的修改就是修改了之前的結構體v。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.