go unsafe package 的学习

本文介绍了Go语言中指针的基本类型及其应用场景,包括如何利用unsafe包进行指针运算及类型转换,并通过示例代码展示了如何获取结构体字段的内存地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

go 不像c 那样直接可以对指针做一些操作,所以go 提供了一个标准的package 来操作指针。go 有三种指针类型:
1.  *  普通指针, 用于传递对象地址,不能进行指针运算

2.  unsafe.Pointer:通用指针类型,用于转换不同类型的指针,不能进行指针运算。

3.  uintptr:用于指针运算,GC 不把 uintptr 当指针,uintptr 无法持有对象。uintptr 类型的目标会被回收


unsafe.Pointer 可以和 普通指针 进行相互转换, unsafe.Pointer 可以和 uintptr 进行相互转换; 也就是说 unsafe.Pointer 是桥梁,可以让任意类型的指针实现相互转换,也可以将任意类型的指针转换为 uintptr 进行指针运算

我们可以看下面的code: 

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	s := struct {
		a byte
		b byte
		c byte
		d int64
	}{0, 0, 0, 0}
	p := unsafe.Pointer(&s)
	up0 := uintptr(p)
	pb := (*byte)(p)
	*pb = 10
	fmt.Println(s)     // 10, 0, 0 , 0

	up := up0 + unsafe.Offsetof(s.b)
	p = unsafe.Pointer(up)
	pb = (*byte)(p)
	*pb = 20
	fmt.Println(s)   //10, 20, 0, 0

	up = up0 + unsafe.Offsetof(s.c)
	p = unsafe.Pointer(up)
	pb = (*byte)(p)
	*pb = 30
	fmt.Println(s)   // 10, 20, 30. 0

	up = up0 + unsafe.Offsetof(s.d)
	p = unsafe.Pointer(up)
	pi := (*int64)(p)
	*pi = 40
	fmt.Println(s)    //10, 20, 30, 40 
}



每种类型都有它的大小和对齐值,可以通过 unsafe.Sizeof 获取其大小,通过 unsafe.Alignof 获取其对齐值,通过 unsafe.Offsetof 获取其偏移量。不过 unsafe.Alignof 获取到的对齐值只是该类型单独使用时的对齐值,不是作为结构体字段时与其它对象间的对齐值,这里用不上,所以需要用 unsafe.Offsetof 来获取字段的偏移量,进而确定其内存地址



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值