github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/01_base/unsafe/pointer_test.go (about)

     1  package unsafe
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"unsafe"
     7  )
     8  
     9  func covPointer() {
    10  	// Go语言是不允许两个指针类型进行转换的。
    11  
    12  	i := 9
    13  	ip := &i
    14  
    15  	//var fp *float64 =(*float64)(ip) // 不让转换
    16  
    17  	var fp *float64 = (*float64)(unsafe.Pointer(ip))
    18  
    19  	fmt.Printf("%T %v\n", fp, fp)
    20  	*fp = *fp * 0.5
    21  	fmt.Printf("%T %g\n", *fp, *fp)
    22  	fmt.Println(i)
    23  }
    24  
    25  func TestCovPointer(t *testing.T) {
    26  	covPointer()
    27  }
    28  
    29  type user struct {
    30  	name string
    31  	age  int
    32  }
    33  
    34  func TestUintptr(t *testing.T) {
    35  	u := new(user)
    36  	fmt.Println(*u)
    37  
    38  	// 因为name 是第一个字段,位置是从0开始,所以可以这样获取
    39  	pName := (*string)(unsafe.Pointer(u))
    40  	*pName = "Alex"
    41  
    42  	// 要找到age 必须找到,age的offset
    43  	fmt.Println("u.age offset ", unsafe.Offsetof(u.age))
    44  
    45  	//up := uintptr(unsafe.Pointer(u)) + unsafe.Offsetof(u.age)
    46  	//fmt.Printf("up : %T %v \n ", up, up)
    47  	//pAge := (*int)(unsafe.Pointer(up))
    48  
    49  	// 表达式非常长,但是也千万不要把他们分段, 这里会牵涉到GC,如果我们的这些临时变量被GC,就不知道是哪块内存了,会引起莫名其妙的问题
    50  	pAge := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(u)) + unsafe.Offsetof(u.age)))
    51  
    52  	*pAge = 32
    53  	fmt.Println(*u)
    54  }