golang之unsafe.Pointer学习笔记

1.概述

 go提供的一种打破系统类型,灵活读写内存的转换操作。使用该方式,可以直接操控内存进行某些数据的读写操作。实际开发中一般不推荐使用,但是在一些底层会使用该方式进行一些相关的操作处理。

2.unsafe.Pointer定义结构&对应类型转化

type Pointer *ArbitraryType
type ArbitraryType int

如上,Pointer实质上的就是一个int指针。在官方文档介绍中,针对其总结如下:

 a.指针类型转化

使用unsafe.Pointer可以转化成任意类型的指针,反过来,其他类型的指针只能转化成unsafe.Pointer类型的指针.

例如:

func main() {

	a := 10
	ptr := unsafe.Pointer(&a)
	fmt.Println(*(*int)(ptr))

	st := &Student{
		Name: "kkk",
	}

	stPtr := unsafe.Pointer(st)

	fmt.Println(*(*Student)(stPtr))
}

结果:

10
{kkk}

如上进行对应类型的转化直接使用,转化之后,直接操作内存地址方式处理.

b.指针类型运算

在c/c++中针对指针的处理是可以进行运算,比如,int *ptr = a[10];可以通过ptr++,ptr--来进行数组数据的访问。在go中,不能直接使用 unsafe.Pointer转化后进行运算的。必选要再转化成uintptr类型方可进行运算.【uintptr类型跟Pointer类型可以相互转化】如下示例:通过指针移动遍历数组元素。

	// 通过指针运算遍历数组
	arr := []int{1, 2, 3, 4, 5}
	for i := 0; i < len(arr); i++ {
		ptr := uintptr(unsafe.Pointer(&arr[0])) + unsafe.Sizeof(arr[0])*uintptr(i)
		fmt.Println(*(*int)(unsafe.Pointer(ptr)))
	}
	fmt.Println()

上述代码截图解释:

golang之unsafe.Pointer学习笔记_第1张图片

 c.指针类型操作结构类型读写

   除了系统自建类型,自定义的一些类型结构,可以通过转化成指针类型进行相关的数据读写操作。

   如下操作一个自定义结构,进行数据覆盖拷贝:

func main(){
   // 自定义类型进行内存读写
	st := &Student{
		Name:   "lx",
		Number: 1,
	}
	hst := unsafe.Pointer(st)
	ptr := (*Student)(unsafe.Pointer(hst))
	fmt.Println("before modify:", *ptr)

	st1 := &Student{
		Name:   "zhang",
		Number: 11,
	}

	// 利用内存改写对应结构内容
	hst1 := unsafe.Pointer(st1)

	hst = hst1 // 将hst1内容写入hst

	ptr = (*Student)(unsafe.Pointer(hst))
	fmt.Println("after modify:", *ptr)
}

  结果:

before modify: {lx 1}
after modify: {zhang 11}

 如上通过结果看出,hst中的数据直接通过内存读写进行了更改。

总结:unsafe.Pointer就是为了方便进行内存读写,不收系统类型的限制,方便灵活,但是一般实际中最好不要使用,因为不安全,可能会出现意想不到的问题。

你可能感兴趣的:(golang笔记,学习)