当前位置: 首页 > news >正文

Golang 中的 unsafe 包详解

Golang 中的 unsafe 包用于在运行时进行低级别的操作。这些操作通常是不安全的,因为可以打破 Golang 的类型安全性和内存安全性,使用 unsafe 包的程序可能会影响可移植性和兼容性。接下来看下 unsafe 包中的类型和函数。

unsafe.Pointer 类型

通常用于类型转换和指针运算,定义如下:

type Pointer *ArbitraryType

可以将其他类型的指针转换为unsafe.Pointer类型,以进行低级别的操作。看个简单示例:

package mainimport ("fmt""unsafe"
)func main() {i := 30ptr1 := &ivar ptr2 *int64 = (*int64)(unsafe.Pointer(ptr1))*ptr2 = 8fmt.Println(i)
}

unsafe.ArbitraryType 类型

定义如下:

type ArbitraryType int

ArbitraryType 仅用于文档目的,实际上并不是 unsafe 包的一部分,用于表示任意 Go 表达式的类型。

unsafe.IntegerType 类型

定义如下:

type IntegerType int

IntegerType 仅用于文档目的,实际上并不是 unsafe 包的一部分,用于表示任意整数类型。

unsafe.Add 函数

定义如下:

func Add(ptr Pointer, len IntegerType) Pointer

用于进行指针的加法运算,将一个指针和指定的偏移量相加,得到一个新的指针。简单示例如下:

package mainimport ("fmt""unsafe"
)func main() {arr := []int{1, 2, 3, 4}index := 2ptr := unsafe.Pointer(&arr[0])newPtr := unsafe.Add(ptr, uintptr(index)*unsafe.Sizeof(arr[0]))cc := (*int)(newPtr)fmt.Println(*cc)fmt.Println(newPtr)
}

unsafe.Sizeof 函数

定义如下:

func Sizeof(x ArbitraryType) uintptr

用于获取一个类型或值的字节大小。简单示例如下:

package mainimport ("fmt""unsafe"
)func main() {var arr [5]intfmt.Println(unsafe.Sizeof(arr)) // 输出: 40fmt.Println(unsafe.Sizeof(0))   // 输出: 8
}

unsafe.Slice 函数

定义如下:

func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType

用于创建一个与原始数组共享底层数据的切片。简单示例如下:

package mainimport ("fmt""unsafe"
)func main() {var arr [5]intarr[0] = 10arr[1] = 20arr[2] = 30arr[3] = 40arr[4] = 50slice := unsafe.Slice(&arr[0], 3)fmt.Println(slice) // 输出: [10 20 30]
}

定义了一个包含5个整数的数组 arr,然后使用 unsafe.Slice 函数创建了一个从索引0开始、长度为3的切片 slice。

unsafe.Offsetof

定义如下:

func Offsetof(x ArbitraryType) uintptr

作用是返回结构体成员在内存中的位置离结构体起始处(结构体的第一个字段的偏移量都是0)的字节数。简单示例如下:

package mainimport ("fmt""unsafe"
)type MyStruct struct {Field1 int64Field2 string
}func main() {var myStruct MyStructfmt.Println(unsafe.Offsetof(myStruct.Field1)) // 输出: 0fmt.Println(unsafe.Offsetof(myStruct.Field2)) // 输出: 8
}

unsafe.Alignof

定义如下:

func Alignof(x ArbitraryType) uintptr

返回参数对齐所需的字节数。对于某些结构体,其字段的内存对齐可能会影响到结构体所占用的内存大小。简单示例如下:

package mainimport ("fmt""unsafe"
)type MyStruct struct {Field1 intField2 string
}func main() {fmt.Println(unsafe.Alignof(int(0)))     // 输出: 8fmt.Println(unsafe.Alignof(string(""))) // 输出: 8fmt.Println(unsafe.Alignof(MyStruct{})) // 输出: 8
}

小结

unsafe 包提供了一些低级别的操作,使用的时候一定要谨慎,必须非常了解自己在做什么,以免引入不安全的问题。

http://www.lryc.cn/news/127559.html

相关文章:

  • linux 的swap、swappiness及kswapd原理【转+自己理解】
  • 什么是Java中的适配器模式?
  • MYSQL线上无锁添加索引
  • 如何实现客户自助服务?打造产品知识库
  • LeetCode环形子数组的最大和(编号918)
  • PhpOffice/PhpSpreadsheet读取和写入Excel
  • jenkins自动化部署Jenkinsfile文件配置
  • 【socket编程简述】TCP UDP 通信总结、TCP连接的三次握手、TCP断开的四次挥手
  • 多线程-死锁
  • P1006 [NOIP2008 提高组] 传纸条
  • 杭电比赛总结
  • dom靶场
  • go struct 的常见问题
  • Linux系统下的性能分析命令
  • 第十三课:QtCmd 命令行终端应用程序开发
  • Jmeter进阶使用:BeanShell实现接口前置和后置操作
  • 【知识分享】高防服务器的防御机制
  • 内网穿透-外远程连接中的RabbitMQ服务
  • 驱动DAY4 字符设备驱动分步注册和ioctl函数点亮LED灯
  • Python爬虫——scrapy_当当网图书管道封装
  • Linux下如何修改CPU 电源工作模式
  • Effective C++学习笔记(8)
  • 学校如何公布录取情况表?这个不用技术的方法,小白老师都能轻松制作
  • Chart GPT免费可用地址共享资源
  • 设计模式十八:中介者模式(Mediator Pattern)
  • 神经网络基础-神经网络补充概念-12-向量化逻辑回归的梯度输出
  • 2023-08-16力扣每日一题
  • 耗资170亿美元?三星电子在得克萨斯州建设新的半导体工厂
  • 黑马项目一阶段面试58题 Web14题(一)
  • 多线程与高并发--------线程池