golang基础(unsafe包使用)
来源:互联网 发布:网络诈骗追回钱的几率 编辑:程序博客网 时间:2024/05/21 11:11
前言
在使用C/C++过程中,很多时候出现的错误都是由于指针操作不合理,导致各种奇奇怪怪的问题。但是,也是由于指针的存在才让C/C++代码的运行效率比其他语言的略高。golang也有指针类型,但是不允许直接对指针类型进行运算。就是像保留指针的有点,规避掉由于指针操作不当而引发的各种奇怪问题。但是有些时候确实需要使用到指针运算的时候,就需要使用到unsafe包了。为什么要用unsafe包呢,说白了,就是让我们在操作指针的时候麻烦些,这样有一定几率会减少由于指针操作不当所引发的问题。
unsafe包接口介绍
1、func Alignof(x ArbitraryType) uintptr
获取变量以多数字节对齐
2、func Offsetof(x ArbitraryType) uintptr
Offsetof返回x所代表的结构体中字段的偏移量,它必须是structValue.field的形式。换言之,该方法返回结构体起始处到该字段之间的字节数。
3、func Sizeof(x ArbitraryType) uintptr
Sizeof获取变量的大小,类似于C/C++中使用sizeof(变量)返回的结果。
unsafe包中的类型
unsafe包中最重要的类型就是Pointer类型,定义如下:
type Pointer *ArbitraryType
**使用规律:
1)任何类型的指针可以转换为Pointer类型。
2)Pointer类型可以转换为任何类型的指针值。
3)uintptr和Pointer类型可以相互转换。
由于指针类型都是不可操作的,所以任意类型的指针必须转换为Pointer类型,然后再由Pointer类型转换为uintptr类型,由于uintptr类型不是指针类型,那么就可以进行运算了。运算完成后,把uintptr类型转换为Pointer类型后再转换为调用者想要的指针类型。**
如果运算后的uintptr运算出错,那就有可能造成代码逻辑混乱,甚至是出现panic。
使用总结
golang如果不使用unsafe包的时候,是不能进行指针运算的。作为比较新的语言,说明,确实在大部分开发过程中都不需要使用指针运算。只有在部分对性能特别敏感或者其他特殊情况下才需要使用指针操作。golang引入了unsafe包,个人觉得目的也是为了开发者在操作的指针的时候都一步操作,而不是直接就操作指针。会给开发者一个缓冲的时间,减少出错的概率。不过,其实对于一些指针操作老手来说,就显得有些多余了。
例子
unsafetest_test.go
package unsafetestimport ( "fmt" "testing" "unsafe")type Person struct { Age int32 //年龄 Name string //名字 Hobit string //爱好}func TestMytest(t *testing.T) { var personA Person var a byte //Alignof 示例 align := unsafe.Alignof(a) fmt.Println("align is: ", align) //Sizeof 示例 size := unsafe.Sizeof(a) fmt.Println("size is: ", size) //Offsetof 示例 offset := unsafe.Offsetof(personA.Name) fmt.Println("offset is : ", offset) //Pointer 示例 nameaddr := (uintptr)(unsafe.Pointer(&(personA.Name))) fmt.Println("nameaddr is: ", nameaddr) personAaddr := (uintptr)(unsafe.Pointer(&(personA))) fmt.Println("nameaddr is: ", personAaddr) personA.Age = 100 personA.Hobit = "run" //指针操作 示例 personAaddr2 := nameaddr - offset fmt.Println("personAaddr2 is: ", personAaddr2) personB := (*Person)(unsafe.Pointer(personAaddr2)) fmt.Println("personB.Age is :", personB.Age) //异常情况 示例 //... 中间逻辑使personAaddr2指向不合法位置 personB = (*Person)(unsafe.Pointer(uintptr(0))) fmt.Println("personB.Age is :", personB.Age)}
- golang基础(unsafe包使用)
- golang中unsafe包浅析
- golang基础(基础包链表使用)
- golang net包基础解析
- Golang unsafe的妙用
- unsafe 包
- golang基础-redis使用
- golang net/http包使用
- golang Context包的使用
- Golang bufio包使用范例
- The unsafe Package in Golang
- golang基础-new_make、recover_panic、append、闭包
- Unsafe 使用
- golang基础(golang压缩文件gzip)
- Golang教程:(七)包
- golang基础-beego_web开发、模板使用(待续)
- Golang flag包使用详解(一)
- golang中goconfig包使用解析
- 网路互联参考模型 存档理解
- 基于DJI-OSDK-ROS 3.4版本demo_camera_gimbal.cpp程序阅读注释
- 分布式事务
- 吃货告诉你,PAAS、IAAS和SAAS之间的区别
- chars拦截到response乱码问题
- golang基础(unsafe包使用)
- 新登月计划:阿里云ET大脑获颁世界互联网领先科技成果奖
- MYSQL存储过程遍历结果集游标 从一张表插入数据到另一张表
- jQuery常用事件和方法总结
- 记录一些意外:ora-09817
- ionic http 数据通信
- 轻松理解skip-gram模型
- 通过URL下载两种类型图片
- python中文分词jieba总结