golang unsafe.Pointer;uintptr;*星号三者之间的关系

关于三者的解释

  • *type 表示具体的指针类型;例如 *int,*string,*structName
  • unsafe.Pointer 想到于c++中的 void*,是所有指针类型的基类。
    任何类型的指针都可以被转化为Pointer;
    Pointer可以被转化为任何类型的指针。
  • uintptr:官方解释
// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr

这里可以看到uintptr其实就是一个可以保存指针指向地址的整数,简单说就是:uintptr是一个可以加减计算的整数。

为什么有了 *星号 和 unsafe.Pointer 还要uintptr呢?因为 前两者都不可以直接进行加减运算,在需要做地址偏移offset运算的时候就需要 uintptr 来辅助了。
看一段代码,使用这三个东西来修改结构的私有变量,因为结构体的私有变量在外面是不可以拿到的,那么就要整一些骚操作了,我们直接通过指针偏移去修改里面的每一个值。

type Person struct {
	age int
	name string
}
func main() {
	var zhangsan Person = Person{25,"zhangsan"}
	
	// 因为结构体变量的起始地址就是第一个成员变量的地址,所以先使用基类型指针unsafe.Pointer
	// 取到结构体变量的首地址,然后就像子类转成基类一样,把unsafe.Pointer转成具体类型*int
	p := (*int)(unsafe.Pointer(&zhangsan))
	*p = 35

	// 这里的逻辑就是把首地址向后偏移一个int的字节大小就行了,因为unsafe.Pointer是不能直接进行加减
	// 计算的,所以要先转成可计算的int类型即uintptr,也就是把zhangsan的地址给到uintptr让它去代劳计算
	// unsafe.Sizeof返回值就是 uintptr;计算得到的结果再给到 unsafe.Pointer 指向偏移后的地址;
	// 最后再转到具体的指针类型 *string,就可以修改私有变量了
	q := (*string)( unsafe.Pointer( uintptr(unsafe.Pointer(&zhangsan))+ unsafe.Sizeof(int(0))) )
	*q = "lisi"

	fmt.Printf("%v",zhangsan)

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值