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

最近阅读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

你可能感兴趣的:(Go)