目录
- 前言
- unsafe.Sizeof、Alignof和Offsetof
- unsafe.Pointer
- 示例:深度相等
- 使用cgo调用C代码
- 关于安全的注意事项
前言
本专栏是笔者在学习《Go程序设计语言》这本书时,对每个章节认为较为重要(容易忘记👻)的知识点记录的笔记,其中也会有少量的思考👀, 现整理成博客分享出来。
如果对专栏感兴趣,跑过去看一眼,书中的每一章都有:《Go程序设计语言》笔记
❗️注意❗️:本专栏不是详细的知识讲解,只是碎片的知识条目,或可作为Go知识点查漏补缺的小工具~
- 对于常见无法静态检测出来的错误:数组访问越界、
nil
指针引用等,动态检测确保这类操作发生时终止程序并给出错误信息; - 自动内存管理(垃圾回收)防止了释放后使用的
bug
; -
unsafe
包可以像普通包一样导入,但其实它是由编译器实现的;提供了对语言内置特性的访问功能;
unsafe.Sizeof、Alignof和Offsetof
-
Sizeof
函数返回参数在内存中占用的字节数; - 当类型的值在内存中对齐时,计算机的加载和写入会很高效;对齐指起始地址是本身大小的整数倍;
-
32
位系统一个字占4
字节,64
位系统一个字占8
字节; -
Alignof
返回参数的对齐方式,布尔和数值类型对齐到他们的长度(最大8
字节),其它类型按字对齐; -
Offsetof
输入参数x
和f
,是成员关系,可以x.f
访问;函数返回f
相对于x
的偏移地址;
unsafe.Pointer
-
unsafe.Pointer
可以存储任何类型的指针;它是可比较的; - 可转换为
uintptr
类型,保存地址的值,这样就可以做地址运算了;但是注意下一条的陷阱; - 一些垃圾回收器会移动变量以减少内存碎片,被称作移动的垃圾回收器;
- 当将
unsafe.Pointer
转换为uintptr
后,进行地址运算,对运算结果进行存取,或许是无意义的:垃圾回收器可能将变量移动过了; -
goroutine
的栈是可扩展的,扩展时也可能包含变量移动,所以不能认为变量地址在生存周期中不变;
示例:深度相等
使用cgo调用C代码
- 一个
Go
程序或许需要调用C
实现的驱动,此时cgo
登场; -
import "C"
会促使go build
工具调用cgo
进行预处理; - 在
import "C"
之前,使用注释来暴露C
的接口,其注释内容为C
的语句,如#include<xxx.h>
等; - 注释中还可以使用
#cgo
指令来指定工具链的选项,如#cgo LDFLAGS: -L/usr/lib -lbz2
添加了库目录/usr/lib
和库文件bz2
; - 在
Go
代码中访问C
的内容,使用C.x、C.func
形式访问,即通过cgo
暴露的C
代码,均在C
作用域内; - 也可以反过来将
Go
代码编译为静态库、动态库,然后通过C
程序来加载和共享;具体参考官网;
关于安全的注意事项
- 大多数程序员永远都不需要使用
unsafe
包; - 避免使用
reflect
和unsafe
;
如有错误 ❌ ,欢迎指正 ☝️~
如有收获 🍗,可以考虑点赞👍/评论💬/收藏⭐️/关注👀,大家共同进步~