[go] unsafe包
2016-04-25 12:48
369 查看
uintptr是go的内置类型,用于指针运算,其底层基于int类型。uintptr不是指针,GC会回收uintptr类型的对象。
如果传入一个指针类型的对象会返回多少呢?
一般情况下,可能是4或8,因为w是指针类型uintptr,而uintptr是平台相关的,在32位系统下大小是4bytes,在64位系统下是8bytes。
要获取值类型的大小,需要对指针变量进行取值:
分别是1、4、8,因为int32类型的对齐值是4bytes,必须是4的倍数,故byte类型要填充3个字节。而填充后,两者的大小和为8bytes,int64对齐值是8bytes,不需要填充,所以用
32位机器下,指针对象的对齐值是4,因为指针类型是uintptr。而结构体的值类型却是8bytes的对齐值,这是因为会先进行字段的对齐,字段最大的对齐值是8bytes,因此结构体值类型的对齐值也是8。
更改结构,验证一下:
unsafe.Sizeof
unsafe.Sizeof函数返回的就是uintptr类型的值(表达式,即值的大小):
var p float64 = 99 fmt.Println(reflect.TypeOf(unsafe.Sizeof(p))) fmt.Println(unsafe.Sizeof(p)) >>> uintptr >>> 8
unsafe.Sizeof接受任意类型的值(表达式),返回其占用的字节数,在上面的例子中float64的大小是8bytes。
如果传入一个指针类型的对象会返回多少呢?
type W struct { a byte b int32 c int64 } var w *W fmt.Println(unsafe.Sizeof(w)) // 4 or 8
一般情况下,可能是4或8,因为w是指针类型uintptr,而uintptr是平台相关的,在32位系统下大小是4bytes,在64位系统下是8bytes。
要获取值类型的大小,需要对指针变量进行取值:
fmt.Println(unsafe.Sizeof(*w)) >>> 16
对齐
在上面的例子中,*w的大小为16,按照常理来说,byte占用1字节,int32占用4字节,int64占用8字节,大小应该是13才对。这是因为发生了对齐,
unsafe.Alignof可以计算对齐值:
unsafe.Alignof(w.a) // type byte unsafe.Alignof(w.b) // type int32 unsafe.Alignof(w.c) // type int64
分别是1、4、8,因为int32类型的对齐值是4bytes,必须是4的倍数,故byte类型要填充3个字节。而填充后,两者的大小和为8bytes,int64对齐值是8bytes,不需要填充,所以用
unsafe.Sizeof获取到结构的大小为
4+4+8=16。
反射包的对齐方法
反射包也有某些方法可用于计算对齐值:unsafe.Alignof(w)等价于
reflect.TypeOf(w).Align。
unsafe.Alignof(w.i)等价于
reflect.Typeof(w.i).FieldAlign()。
结构体的对齐值
如果我们计算的是结构体的对齐值而不是某个字段或者基本类型,那么值会是多少呢?type W struct { a byte b int32 c int64 } var w *W var w2 W fmt.Println(unsafe.Alignof(w)) fmt.Println(unsafe.Alignof(w2)) fmt.Println(refelct.TypeOf(w).Elem().Align()) >>> 4 >>> 8 >>> 8
32位机器下,指针对象的对齐值是4,因为指针类型是uintptr。而结构体的值类型却是8bytes的对齐值,这是因为会先进行字段的对齐,字段最大的对齐值是8bytes,因此结构体值类型的对齐值也是8。
更改结构,验证一下:
type W struct { a byte b int32 c int32 } var w W fmt.Println(unsafe.Alignof(w)) >>> 4
相关文章推荐
- 剑指offer(12):数值的整数次方
- 详解Bootstrap网格系统
- 去掉网址中的 html编码
- 剑指offer(11):二进制中1的个数
- CSS3D变换/立方体旋转效果
- SharedPreferences(系统偏好设置)(二)——PreferenceActivity
- JS中判断null、undefined与NaN的方法
- 剑指offer(10):矩形覆盖问题
- 2、JavaScript快速入门(1)
- javascript的2种继承方式详解
- 1、HTML快速简单复习
- Bootstrap学习笔记
- html5 File API实现带有进度提示的文件上传
- JavaScript模块化编程思想演变
- jquery中的页面加载方法load()
- 剑指offer:复杂链表的复制
- angularjs 上拉加载,下拉刷新数据功能
- 關於js對象創建
- JQuery中eq()和get()的区别
- javascript的基础学习笔记