1. 程式人生 > >十四、Go基礎程式設計:複合型別—指標

十四、Go基礎程式設計:複合型別—指標

指標是一個代表著某個記憶體地址的值。這個記憶體地址往往是在記憶體中儲存的另一個變數的值的起始位置。Go語言對指標的支援介於Java語言和C/C++語言之間,它既沒有想Java語言那樣取消了程式碼對指標的直接操作的能力,也避免了C/C++語言中由於對指標的濫用而造成的安全和可靠性問題。

 

基本操作

Go語言雖然保留了指標,但與其它程式語言不同的是:


預設值 nil,沒有 NULL 常量
操作符 “&” 取變數地址, “*” 通過指標訪問目標物件
不⽀持指標運算,不⽀持 “->” 運算子,直接⽤ “.” 訪問目標成員
 

func main() {
    var a int = 10              //宣告一個變數,同時初始化
    fmt.Printf("&a = %p\n", &a) //操作符 "&" 取變數地址

    var p *int = nil //宣告一個變數p, 型別為 *int, 指標型別
    p = &a
    fmt.Printf("p = %p\n", p)
    fmt.Printf("a = %d, *p = %d\n", a, *p)

    *p = 111 //*p操作指標所指向的記憶體,即為a
    fmt.Printf("a = %d, *p = %d\n", a, *p)
}

new函式

表示式new(T)將建立一個T型別的匿名變數,所做的是為T型別的新值分配並清零一塊記憶體空間,然後將這塊記憶體空間的地址作為結果返回,而這個結果就是指向這個新的T型別值的指標值,返回的指標型別為*T。

func main() {
    var p1 *int
    p1 = new(int)              //p1為*int 型別, 指向匿名的int變數
    fmt.Println("*p1 = ", *p1) //*p1 =  0

    p2 := new(int) //p2為*int 型別, 指向匿名的int變數
    *p2 = 111
    fmt.Println("*p2 = ", *p2) //*p1 =  111
}

我們只需使用new()函式,無需擔心其記憶體的生命週期或怎樣將其刪除,因為Go語言的記憶體管理系統會幫我們打理一切。

指標做函式引數

func swap01(a, b int) {
    a, b = b, a
    fmt.Printf("swap01 a = %d, b = %d\n", a, b)
}

func swap02(x, y *int) {
    *x, *y = *y, *x
}

func main() {
    a := 10
    b := 20

    //swap01(a, b) //值傳遞
    swap02(&a, &b) //變數地址傳遞
    fmt.Printf("a = %d, b = %d\n", a, b)
}