開源技術教學文件網 使用指標 (Pointer)

最後修改日期為 JUN 6, 2019

前言

如同其他的編譯語言 (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 Yahoo
追蹤本站
Facebook Facebook Twitter