轉(zhuǎn)載原文: https://blog.csdn.net/cbmljs/article/details/82983639
這里有一些關(guān)于unsafe.Pointer和uintptr的事實:
- uintptr是一個整數(shù)類型梅誓。
- 即使uintptr變量仍然有效,由uintptr變量表示的地址處的數(shù)據(jù)也可能被GC回收管钳。
- unsafe.Pointer是一個指針類型。
- 但是unsafe.Pointer值不能被取消引用。
- 如果unsafe.Pointer變量仍然有效,則由unsafe.Pointer變量表示的地址處的數(shù)據(jù)不會被GC回收聪姿。
- unsafe.Pointer是一個通用的指針類型,就像* int等乙嘀。
由于uintptr是一個整數(shù)類型,uintptr值可以進行算術(shù)運算破喻。 所以通過使用uintptr和unsafe.Pointer虎谢,我們可以繞過限制,* T值不能在Golang中計算偏移量:
package main
import (
"fmt"
"unsafe"
)
func main() {
a := [4]int{0, 1, 2, 3}
p1 := unsafe.Pointer(&a[1])
p3 := unsafe.Pointer(uintptr(p1) + 2 * unsafe.Sizeof(a[0]))
*(*int)(p3) = 6
fmt.Println("a =", a) // a = [0 1 2 6]
// ...
type Person struct {
name string
age int
gender bool
}
who := Person{"John", 30, true}
pp := unsafe.Pointer(&who)
pname := (*string)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(who.name)))
page := (*int)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(who.age)))
pgender := (*bool)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(who.gender)))
*pname = "Alice"
*page = 28
*pgender = false
fmt.Println(who) // {Alice 28 false}
}