修正半角标点符号

This commit is contained in:
kimw
2018-05-27 16:51:15 -04:00
parent fb3359fb4e
commit 0ab7557665
39 changed files with 85 additions and 86 deletions

View File

@@ -38,11 +38,11 @@ struct{ bool; int16; float64 } // 2 words 3words
关于内存地址对齐算法的细节超出了本书的范围也不是每一个结构体都需要担心这个问题不过有效的包装可以使数据结构更加紧凑译注未来的Go语言编译器应该会默认优化结构体的顺序当然应该也能够指定具体的内存布局相同讨论请参考 [Issue10014](https://github.com/golang/go/issues/10014) ),内存使用率和性能都可能会受益。
`unsafe.Alignof` 函数返回对应参数的类型需要对齐的倍数. 和 Sizeof 类似, Alignof 也是返回一个常量表达式, 对应一个常量. 通常情况下布尔和数字类型需要对齐到它们本身的大小(最多8个字节), 其它的类型对齐到机器字大小.
`unsafe.Alignof` 函数返回对应参数的类型需要对齐的倍数和 Sizeof 类似 Alignof 也是返回一个常量表达式对应一个常量通常情况下布尔和数字类型需要对齐到它们本身的大小最多8个字节其它的类型对齐到机器字大小
`unsafe.Offsetof` 函数的参数必须是一个字段 `x.f`, 然后返回 `f` 字段相对于 `x` 起始地址的偏移量, 包括可能的空洞.
`unsafe.Offsetof` 函数的参数必须是一个字段 `x.f`然后返回 `f` 字段相对于 `x` 起始地址的偏移量包括可能的空洞
图 13.1 显示了一个结构体变量 x 以及其在32位和64位机器上的典型的内存. 灰色区域是空洞.
图 13.1 显示了一个结构体变量 x 以及其在32位和64位机器上的典型的内存灰色区域是空洞
```Go
var x struct {

View File

@@ -2,7 +2,7 @@
Go程序可能会遇到要访问C语言的某些硬件驱动函数的场景或者是从一个C++语言实现的嵌入式数据库查询记录的场景或者是使用Fortran语言实现的一些线性代数库的场景。C语言作为一个通用语言很多库会选择提供一个C兼容的API然后用其他不同的编程语言实现译者Go语言需要也应该拥抱这些巨大的代码遗产
在本节中我们将构建一个简易的数据压缩程序使用了一个Go语言自带的叫cgo的用于支援C语言函数调用的工具。这类工具一般被称为 *foreign-function interfaces* 简称ffi, 并且在类似工具中cgo也不是唯一的。SWIG http://swig.org 是另一个类似的且被广泛使用的工具SWIG提供了很多复杂特性以支援C++的特性但SWIG并不是我们要讨论的主题。
在本节中我们将构建一个简易的数据压缩程序使用了一个Go语言自带的叫cgo的用于支援C语言函数调用的工具。这类工具一般被称为 *foreign-function interfaces* 简称ffi并且在类似工具中cgo也不是唯一的。SWIGhttp://swig.org是另一个类似的且被广泛使用的工具SWIG提供了很多复杂特性以支援C++的特性但SWIG并不是我们要讨论的主题。
在标准库的`compress/...`子包有很多流行的压缩算法的编码和解码实现包括流行的LZW压缩算法Unix的compress命令用的算法和DEFLATE压缩算法GNU gzip命令用的算法。这些包的API的细节虽然有些差异但是它们都提供了针对 io.Writer类型输出的压缩接口和提供了针对io.Reader类型输入的解压缩接口。例如
@@ -37,7 +37,7 @@ bzip2压缩算法是基于优雅的Burrows-Wheeler变换算法运行速度
// pointers to Go variables.
```
要使用libbzip2我们需要先构建一个bz_stream结构体用于保持输入和输出缓存。然后有三个函数BZ2_bzCompressInit用于初始化缓存BZ2_bzCompress用于将输入缓存的数据压缩到输出缓存BZ2_bzCompressEnd用于释放不需要的缓存。目前不要担心包的具体结构, 这个例子的目的就是演示各个部分如何组合在一起的。)
要使用libbzip2我们需要先构建一个bz_stream结构体用于保持输入和输出缓存。然后有三个函数BZ2_bzCompressInit用于初始化缓存BZ2_bzCompress用于将输入缓存的数据压缩到输出缓存BZ2_bzCompressEnd用于释放不需要的缓存。目前不要担心包的具体结构这个例子的目的就是演示各个部分如何组合在一起的。)
我们可以在Go代码中直接调用BZ2_bzCompressInit和BZ2_bzCompressEnd但是对于BZ2_bzCompress我们将定义一个C语言的包装函数用它完成真正的工作。下面是C代码对应一个独立的文件。
@@ -204,7 +204,7 @@ $ ./bzipper < /usr/share/dict/words | bunzip2 | sha256sum
126a4ef38493313edc50b86f90dfdaf7c59ec6c948451eac228f2f3a8ab1a6ed -
```
我们演示了如何将一个C语言库链接到Go语言程序。相反, 将Go编译为静态库然后链接到C程序或者将Go程序编译为动态库然后在C程序中动态加载也都是可行的译注在Go1.5中Windows系统的Go语言实现并不支持生成C语言动态库或静态库的特性。不过好消息是目前已经有人在尝试解决这个问题具体请访问 [Issue11058](https://github.com/golang/go/issues/11058) 。这里我们只展示的cgo很小的一些方面更多的关于内存管理、指针、回调函数、中断信号处理、字符串、errno处理、终结器以及goroutines和系统线程的关系等有很多细节可以讨论。特别是如何将Go语言的指针传入C函数的规则也是异常复杂的译注简单来说要传入C函数的Go指针指向的数据本身不能包含指针或其他引用类型并且C函数在返回后不能继续持有Go指针并且在C函数返回之前Go指针是被锁定的不能导致对应指针数据被移动或栈的调整部分的原因在13.2节有讨论到但是在Go1.5中还没有被明确译注Go1.6将会明确cgo中的指针使用规则。如果要进一步阅读可以从 https://golang.org/cmd/cgo 开始。
我们演示了如何将一个C语言库链接到Go语言程序。相反将Go编译为静态库然后链接到C程序或者将Go程序编译为动态库然后在C程序中动态加载也都是可行的译注在Go1.5中Windows系统的Go语言实现并不支持生成C语言动态库或静态库的特性。不过好消息是目前已经有人在尝试解决这个问题具体请访问 [Issue11058](https://github.com/golang/go/issues/11058) 。这里我们只展示的cgo很小的一些方面更多的关于内存管理、指针、回调函数、中断信号处理、字符串、errno处理、终结器以及goroutines和系统线程的关系等有很多细节可以讨论。特别是如何将Go语言的指针传入C函数的规则也是异常复杂的译注简单来说要传入C函数的Go指针指向的数据本身不能包含指针或其他引用类型并且C函数在返回后不能继续持有Go指针并且在C函数返回之前Go指针是被锁定的不能导致对应指针数据被移动或栈的调整部分的原因在13.2节有讨论到但是在Go1.5中还没有被明确译注Go1.6将会明确cgo中的指针使用规则。如果要进一步阅读可以从 https://golang.org/cmd/cgo 开始。
**练习 13.3** 使用sync.Mutex以保证bzip2.writer在多个goroutines中被并发调用是安全的。

View File

@@ -16,5 +16,4 @@ Go语言的实现刻意隐藏了很多底层细节。我们无法知道一个结
要注意的是unsafe包是一个采用特殊方式实现的包。虽然它可以和普通包一样的导入和使用但它实际上是由编译器实现的。它提供了一些访问语言内部特性的方法特别是内存布局相关的细节。将这些特性封装到一个独立的包中是为在极少数情况下需要使用的时候同时引起人们的注意译注因为看包的名字就知道使用unsafe包是不安全的。此外有一些环境因为安全的因素可能限制这个包的使用。
不过unsafe包被广泛地用于比较低级的包, 例如runtime、os、syscall还有net包等因为它们需要和操作系统密切配合但是对于普通的程序一般是不需要使用unsafe包的。
不过unsafe包被广泛地用于比较低级的包例如runtime、os、syscall还有net包等因为它们需要和操作系统密切配合但是对于普通的程序一般是不需要使用unsafe包的。