golang unsafe包基本使用

Posted lemonzwt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

  

以上是关于golang unsafe包基本使用的主要内容,如果未能解决你的问题,请参考以下文章

golang 字节对齐

Golang:基本数据类型

Golang:基本数据类型

Golang basic_leaming基本数据类型

Golang basic_leaming基本数据类型

golang unsafe.Pointer使用原则以及 uintptr 隐藏的坑