Go语言圣经
  • 前言
  • Go语言起源
  • Go语言项目
  • 本书的组织
  • 更多的信息
  • 致谢
  • 入门
    • Hello, World
    • 命令行参数
    • 查找重复的行
    • GIF动画
    • 获取URL
    • 并发获取多个URL
    • Web服务
    • 本章要点
  • 程序结构
    • 命名
    • 声明
    • 变量
    • 赋值
    • 类型
    • 包和文件
    • 作用域
  • 基础数据类型
    • 整型
    • 浮点数
    • 复数
    • 布尔型
    • 字符串
    • 常量
  • 复合数据类型
    • 数组
    • Slice
    • Map
    • 结构体
    • JSON
    • 文本和HTML模板
  • 函数
    • 函数声明
    • 递归
    • 多返回值
    • 错误
    • 函数值
    • 匿名函数
    • 可变参数
    • Deferred函数
    • Panic异常
    • Recover捕获异常
  • 方法
    • 方法声明
    • 基于指针对象的方法
    • 通过嵌入结构体来扩展类型
    • 方法值和方法表达式
    • 示例: Bit数组
    • 封装
  • 接口
    • 接口是合约
    • 接口类型
    • 实现接口的条件
    • flag.Value接口
    • 接口值
    • sort.Interface接口
    • http.Handler接口
    • error接口
    • 示例: 表达式求值
    • 类型断言
    • 基于类型断言识别错误类型
    • 通过类型断言查询接口
    • 类型分支
    • 示例: 基于标记的XML解码
    • 补充几点
  • Goroutines和Channels
    • Goroutines
    • 示例: 并发的Clock服务
    • 示例: 并发的Echo服务
    • Channels
    • 并发的循环
    • 示例: 并发的Web爬虫
    • 基于select的多路复用
    • 示例: 并发的字典遍历
    • 并发的退出
    • 示例: 聊天服务
  • 基于共享变量的并发
    • 竞争条件
    • sync.Mutex互斥锁
    • sync.RWMutex读写锁
    • 内存同步
    • sync.Once初始化
    • 竞争条件检测
    • 示例: 并发的非阻塞缓存
    • Goroutines和线程
  • 包和工具
    • 包简介
    • 导入路径
    • 包声明
    • 导入声明
    • 包的匿名导入
    • 包和命名
    • 工具
  • 测试
    • go test
    • 测试函数
    • 测试覆盖率
    • 基准测试
    • 剖析
    • 示例函数
  • 反射
    • 为何需要反射?
    • reflect.Type和reflect.Value
    • Display递归打印
    • 示例: 编码S表达式
    • 通过reflect.Value修改值
    • 示例: 解码S表达式
    • 获取结构体字段标识
    • 显示一个类型的方法集
    • 几点忠告
  • 底层编程
    • unsafe.Sizeof, Alignof 和 Offsetof
    • unsafe.Pointer
    • 示例: 深度相等判断
    • 通过cgo调用C代码
    • 几点忠告
  • 附录
    • 附录A:原文勘误
    • 附录B:作者译者
    • 附录C:译文授权
    • 附录D:其它语言
Powered by GitBook
On this page

Was this helpful?

  1. 底层编程

几点忠告

我们在前一章结尾的时候,我们警告要谨慎使用reflect包。那些警告同样适用于本章的unsafe包。

高级语言使得程序员不用在关心真正运行程序的指令细节,同时也不再需要关注许多如内存布局之类的实现细节。因为高级语言这个绝缘的抽象层,我们可以编写安全健壮的,并且可以运行在不同操作系统上的具有高度可移植性的程序。

但是unsafe包,它让程序员可以透过这个绝缘的抽象层直接使用一些必要的功能,虽然可能是为了获得更好的性能。但是代价就是牺牲了可移植性和程序安全,因此使用unsafe包是一个危险的行为。我们对何时以及如何使用unsafe包的建议和我们在11.5节提到的Knuth对过早优化的建议类似。大多数Go程序员可能永远不会需要直接使用unsafe包。当然,也永远都会有一些需要使用unsafe包实现会更简单的场景。如果确实认为使用unsafe包是最理想的方式,那么应该尽可能将它限制在较小的范围,那样其它代码就忽略unsafe的影响。

现在,赶紧将最后两章抛入脑后吧。编写一些实实在在的应用是真理。请远离reflect的unsafe包,除非你确实需要它们。

最后,用Go快乐地编程。我们希望你能像我们一样喜欢Go语言。

Previous通过cgo调用C代码Next附录

Last updated 4 years ago

Was this helpful?