golang unsafe包基本使用

import (
	"testing"
	"unsafe"
)

type Users struct {
	Age  int32
	Name string
}

func TestUnsafe(t *testing.T) {
	var user Users
	var a byte

	/*
	  func Alignof(x ArbitraryType) uintptr
	  获取变量以多数字节对齐
	*/
	align := unsafe.Alignof(a)
	t.Log("align is: ", align)

	/*
		  func Offsetof(x ArbitraryType) uintptr
		Offsetof返回x所代表的结构体中字段的偏移量,它必须是structValue.field的形式。该方法返回结构体起始处到该字段之间的字节数。
	*/
	offset := unsafe.Offsetof(user.Name)
	t.Log("offset is:", offset)

	/*
	  func Sizeof(x ArbitraryType) uintptr
	  Sizeof获取变量的大小,类似于C/C++中使用sizeof(变量)返回的结果。
	*/
	size := unsafe.Sizeof(a)
	t.Log("size is:", size)

	/*
		    Pointer类型
			  type Pointer *ArbitraryType
		    使用说明:
		    任何类型的指针可以转换为Pointer类型。
		    Pointer类型可以转换为任何类型的指针值。
		    uintptr和Pointer类型可以相互转换。
		    由于指针类型都是不可操作的,所以任意类型的指针必须转换为Pointer类型,
		    再由Pointer类型转换为uintptr类型,由于uintptr类型不是指针类型,就可以进行运算了。
		    运算完成后,把uintptr类型转换为Pointer类型后再转换为调用者想要的指针类型。
	*/
	nameAddress := (uintptr)(unsafe.Pointer(&(user.Name)))
	t.Log("nameAddress is:", nameAddress)
	userAddr := (uintptr)(unsafe.Pointer(&(user)))
	t.Log("userAddr is:", userAddr)
	user.Age = 10
	user.Name = "mike"

	//操作实例
	userAddr2 := nameAddress - offset
	t.Log("userAdd2 is:", userAddr2)
	user2 := (*Users)(unsafe.Pointer(userAddr2))
	t.Log("user2.Age is:", user2.Age)
}

  

posted @ 2019-08-13 21:47  不骄不傲  阅读(884)  评论(0编辑  收藏  举报