欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Golang源码笔记--unsafe.Pointer与uintptr

程序员文章站 2022-03-04 18:51:22
...

最近阅读golang源码时,经常遇到unsafe.Pointer和uintptr对结构体指针做一些操作,看的有点懵,特别发了点时间研究了下,并有些心得。

先看下官方定义:

  • A pointer value of any type can be converted to a Pointer.
  • A Pointer can be converted to a pointer value of any type.
  • A uintptr can be converted to a Pointer.
  • A Pointer can be converted to a uintptr.

通过上面的定义和在使用中的一些总结,我把它与C语言的指针做对比:

  • unsafe.Pointer类似于C语言的空指针(void *)。
  • uintptr类似于C语言的无符号字符指针(unsigned char *)。

unsafe.Pointer主要用于不同类型指针的转换,比如把A类型转成B类型,基本操作是:

v1 := uint(1)
v2 := int(2)

p := &v1		// p的类型是(uint *)
p = &v2			// 会报错,不能把(int *) 赋给(uint *)

// 可以通过unsafe.Pointer实现
p = (*uint)(unsafe.Pointer(&v2)) 

先把v2转成空指针,然后空指针就可以转成任意其它类型的指针了。

uintptr主要用于指针的四则运算,如希望把一个int指针首地址向后偏移10个字节,我们知道在C语言中,如果要偏移10个字符,要先把指针转成unsigned char类型指针,再做运算,直接指针加10是错的,实际是偏移了40个字节。golang也一样,需要先转成uintptr,一个类似于unsigned char *类型的指针:

v := uint(1)
p = &v

p = (*uint)(safe.Pointer(uintptr(safe.Pointer(p)) + 10))

参考文档:
https://my.oschina.net/xinxingegeya/blog/729673