兄弟連go教程(6)指標

尹成發表於2018-07-04
⽀支援指標型別 *T,指標的指標 **T,以及包含包名字首的 *<package>.T。
•預設值 nil,沒有 NULL 常量。
•操作符 "&" 取變數地址,"*" 透過指標訪問⺫⽬目標物件。
•不⽀支援指標運算,不⽀支援 "->" 運算子,直接⽤用 "." 訪問⺫⽬目標成員。
func main() {
type data struct{ a int }
var d = data{1234}
var p *data
p = &d

fmt.Printf("%p, %v\n", p, p.a) // 直接⽤用指標訪問⺫⽬目標物件成員,⽆無須轉換。
}


輸出:
0x2101ef018, 1234


不能對指標做加減法等運算。
x := 1234
p := &x
p++ // Error: invalid operation: p += 1 (mismatched types *int and int)


可以在 unsafe.Pointer 和任意型別指標間進⾏行轉換。
func main() {
x := 0x12345678
p := unsafe.Pointer(&x) // *int -> Pointer
n := (*[4]byte)(p) // Pointer -> *[4]byte
for i := 0; i < len(n); i++ {
fmt.Printf("%X ", n[i])
}
}


輸出:
78 56 34 12


返回區域性變數指標是安全的,編譯器會根據需要將其分配在 GC Heap 上。
func test() *int {
x := 100
return &x // 在堆上分配 x 記憶體。但在內聯時,也可能直接分配在⺫⽬目標棧。
}


將 Pointer 轉換成 uintptr,可變相實現指標運算。
func main() {
d := struct {
s string
x int
}{"abc", 100}
p := uintptr(unsafe.Pointer(&d)) // *struct -> Pointer -> uintptr
p += unsafe.Offsetof(d.x) // uintptr + offset

p2 := unsafe.Pointer(p) // uintptr -> Pointer
px := (*int)(p2) // Pointer -> *int
*px = 200 // d.x = 200
fmt.Printf("%#v\n", d)
}


輸出:
struct { s string; x int }{s:"abc", x:200}


注意:GC 把 uintptr 當成普通整數物件,它⽆無法阻⽌止 "關聯" 物件被回收。



尹成老師

QQ77025077 

微信18510341407

所有視訊在尹成學院

www.yinchengxueyuan.com

尹成百度雲請聯絡QQ475318423



相關文章