[Golang] 程式設計教學:使用指標 (Pointer)

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    如同其他的編譯語言 (compiled language),Go 支援指標 (pointer)。在 C/C++ 中,指標是必經的門檻;但指標對初學者來說不是很好懂,時常會因誤用指標而造成 segment fault 等錯誤,許多程式學習者對指標有不好的回憶。不過,在 Go 裡面,指標比較簡化,不僅沒有指標運算,也不需要手動控制記憶體釋放。

    建立指標

    指標本身存的值是指向另一個值的記憶體位置 (memory address),我們通常不會直接使用指標的值,而會透過指標間接操作另一個值。在以下實例中,我們建立一個指向整數的指標:

    package main
     
    import (
        "fmt"
        "log"
    )
     
    func main() {
        n := 2
     
        // Reference the adress from the variable.
        nPtr := &n
     
        // Print out the address.
        fmt.Println(nPtr)
     
        // Dereference the pointer to get the value.
        if !(*nPtr == 2) {
            log.Fatal("Wrong value")
        }
    }
    

    動態配置記憶體

    我們也可以動態配置記憶體,見下例:

    package main
     
    import (
        "fmt"
        "log"
    )
     
    func main() {
        // Allocate a chunk of memory.
        nPtr := new(int)
     
        // Assign the value indirectly.
        *nPtr = 2
     
        // Print out the address.
        fmt.Println(nPtr)
     
        // Dereference the pointer to get the value.
        if !(*nPtr == 2) {
            log.Fatal("Wrong value")
        }
    }
    

    實際上,我們比較少對基礎型別進行動態記憶體分配,但我們可以對結構等複合型別動態配置記憶體,如下例:

    package main
     
    import (
        "fmt"
    )
     
    type Point struct {
        x float64
        y float64
    }
     
    func main() {
        p := new(Point)
     
        p.x = 3.0
        p.y = 4.0
     
        fmt.Println(fmt.Sprintf("(%.2f, %.2f)", p.x, p.y))
    }
    

    對結構動態分配記憶體相當有用,Go 物件導向程式大量使用這種語法。

    我們前述的 make 函式其實也是動態分配記憶體的一種語法,但 make 回傳的不是指標,而是該型別本身;因此,我們不需要使用指標的語法操作陣列、切片和 map,這是 Go 簡化語法的一種方式。

    結語

    在 Go 裡面,指標除了用來和 C 函式庫互動外,當變數較大時,傳遞指標較傳遞整個變數有效率得多,日後談到函式和物件時都會用到指標。由於 Go 不需手動管理記憶體,也沒有指標運算,Go 指標較 C 指標簡化許多。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk