mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 12:32:21 +00:00
Merge branch 'master' of github.com:chai2010/advanced-go-programming-book
This commit is contained in:
commit
ab5a456185
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
- 作者:柴树杉,Github [@chai2010](https://github.com/chai2010),Twitter [@chaishushan](https://twitter.com/chaishushan)
|
- 作者:柴树杉,Github [@chai2010](https://github.com/chai2010),Twitter [@chaishushan](https://twitter.com/chaishushan),主页 https://chai2010.cn/about
|
||||||
- 作者:曹春晖,Github [@cch123](https://github.com/cch123)
|
- 作者:曹春晖,Github [@cch123](https://github.com/cch123)
|
||||||
- 网址:https://github.com/chai2010/advanced-go-programming-book
|
- 网址:https://github.com/chai2010/advanced-go-programming-book
|
||||||
- Star历史:https://starcharts.herokuapp.com/chai2010/advanced-go-programming-book.svg
|
- Star历史:https://starcharts.herokuapp.com/chai2010/advanced-go-programming-book.svg
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# 附录C:作者简介
|
# 附录C:作者简介
|
||||||
|
|
||||||
- 柴树杉(Github [@chai2010](https://github.com/chai2010); Twitter [@chaishushan](https://twitter.com/chaishushan))国内第一批Go语言爱好者,创建了最早的QQ讨论组和golang-china邮件列表,组织 [Go语言官方文档](https://github.com/golang-china) 和 [《Go语言圣经》](https://github.com/golang-china/gopl-zh) 的翻译工作,Go语言代码的贡献者。目前在[青云QingCloud](https://www.qingcloud.com/)从事开源的多云应用管理平台[OpenPitrix](https://github.com/openpitrix/openpitrix)开发工作。
|
- 柴树杉(Github [@chai2010](https://github.com/chai2010); Twitter [@chaishushan](https://twitter.com/chaishushan))国内第一批Go语言爱好者,创建了最早的QQ讨论组和golang-china邮件列表,组织 [Go语言官方文档](https://github.com/golang-china) 和 [《Go语言圣经》](https://github.com/golang-china/gopl-zh) 的翻译工作,Go语言代码的贡献者。WebAssembly技术爱好者,著有 [《WebAssembly标准入门》](https://github.com/chai2010/awesome-wasm-zh/blob/master/webassembly-primer.md) (人民邮电即将出版)和 [《C/C++面向wasm编程——Emscripten工程实践》](https://github.com/3dgen/cppwasm-book) (开源图书)。目前在[青云QingCloud](https://www.qingcloud.com/)从事开源的多云应用管理平台[OpenPitrix](https://github.com/openpitrix/openpitrix)开发工作。
|
||||||
- 曹春晖(Gtihub [@cch123](https://github.com/cch123))在 web 领域工作多年,开源爱好者。对大型网站系统的架构和相关工具的实现很感兴趣,并且有一些研究成果。目前在滴滴平台技术部工作。
|
- 曹春晖(Gtihub [@cch123](https://github.com/cch123))在 web 领域工作多年,开源爱好者。对大型网站系统的架构和相关工具的实现很感兴趣,并且有一些研究成果。目前在滴滴平台技术部工作。
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ type gatefs struct {
|
|||||||
func (fs gatefs) Lstat(p string) (os.FileInfo, error) {
|
func (fs gatefs) Lstat(p string) (os.FileInfo, error) {
|
||||||
fs.enter()
|
fs.enter()
|
||||||
defer fs.leave()
|
defer fs.leave()
|
||||||
return fs.Lstat(p)
|
return fs.fs.Lstat(p)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -82,10 +82,10 @@ DATA ·count+3(SB)/1,$4
|
|||||||
|
|
||||||
// or
|
// or
|
||||||
|
|
||||||
DATA ·count+0(SB)/4,$0x01020304
|
DATA ·count+0(SB)/4,$0x04030201
|
||||||
```
|
```
|
||||||
|
|
||||||
因为X86处理器是小端序,因此用十六进制0x01020304初始化全部的4个字节,和用1、2、3、4逐个初始化4个字节是一样的效果。
|
因为X86处理器是小端序,因此用十六进制0x04030201初始化全部的4个字节,和用1、2、3、4逐个初始化4个字节是一样的效果。
|
||||||
|
|
||||||
最后还需要在Go语言中声明对应的变量(和C语言头文件声明变量的作用类似),这样垃圾回收器会根据变量的类型来管理其中的指针相关的内存数据。
|
最后还需要在Go语言中声明对应的变量(和C语言头文件声明变量的作用类似),这样垃圾回收器会根据变量的类型来管理其中的指针相关的内存数据。
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ GLOBL ·float32Value(SB),$4
|
|||||||
DATA ·float32Value+0(SB)/4,$1.5 // var float32Value = 1.5
|
DATA ·float32Value+0(SB)/4,$1.5 // var float32Value = 1.5
|
||||||
|
|
||||||
GLOBL ·float64Value(SB),$8
|
GLOBL ·float64Value(SB),$8
|
||||||
DATA ·float64Value(SB)/4,$0x01020304 // bit 方式初始化
|
DATA ·float64Value(SB)/8,$0x01020304 // bit 方式初始化
|
||||||
```
|
```
|
||||||
|
|
||||||
我们在上一节精简的算术指令中都是针对整数,如果要通过整数指令处理浮点数的加减法必须根据浮点数的运算规则进行:先对齐小数点,然后进行整数加减法,最后再对结果进行归一化并处理精度舍入问题。不过在目前的主流CPU中,都提针对浮点数提供了专有的计算指令。
|
我们在上一节精简的算术指令中都是针对整数,如果要通过整数指令处理浮点数的加减法必须根据浮点数的运算规则进行:先对齐小数点,然后进行整数加减法,最后再对结果进行归一化并处理精度舍入问题。不过在目前的主流CPU中,都提针对浮点数提供了专有的计算指令。
|
||||||
@ -263,7 +263,7 @@ var helloworld []byte
|
|||||||
GLOBL ·helloworld(SB),$24 // var helloworld []byte("Hello World!")
|
GLOBL ·helloworld(SB),$24 // var helloworld []byte("Hello World!")
|
||||||
DATA ·helloworld+0(SB)/8,$text<>(SB) // StringHeader.Data
|
DATA ·helloworld+0(SB)/8,$text<>(SB) // StringHeader.Data
|
||||||
DATA ·helloworld+8(SB)/8,$12 // StringHeader.Len
|
DATA ·helloworld+8(SB)/8,$12 // StringHeader.Len
|
||||||
DATA ·helloworld+16(SB)/8,$16 // StringHeader.Len
|
DATA ·helloworld+16(SB)/8,$16 // StringHeader.Cap
|
||||||
|
|
||||||
GLOBL text<>(SB),$16
|
GLOBL text<>(SB),$16
|
||||||
DATA text<>+0(SB)/8,$"Hello Wo" // ...string data...
|
DATA text<>+0(SB)/8,$"Hello Wo" // ...string data...
|
||||||
@ -344,7 +344,7 @@ GLOBL file_private<>(SB),$1
|
|||||||
|
|
||||||
这样可以减少私有标识符对其它文件内标识符命名的干扰。
|
这样可以减少私有标识符对其它文件内标识符命名的干扰。
|
||||||
|
|
||||||
此外,Go汇编语言还在"textflag.h"文件定义了一些标志。其中用于变量的标志有DUPOK、RODATA和NOPTR几个。DUPOK表示该变量对应的标识符可能有多个,在链接时只选择其中一个即可(一般用于合并相同的常量字符串,减少重复数据占用的空间)。RODATA标志表示将变量定义在只读内存段,因此后续任何对此变量的修改操作将导致异常(panic也无法捕获)。NOPTR则表示此变量的内部不含指针数据,让垃圾回收器忽略对该变量的扫描。如果变量已经在Go代码中声明过的话,Go编译器会自动分析出该变量是否包含指针,这种时候可以不用手写NOPTR标志。
|
此外,Go汇编语言还在"textflag.h"文件定义了一些标志。其中用于变量的标志有DUPOK、RODATA和NOPTR几个。DUPOK表示该变量对应的标识符可能有多个,在链接时只选择其中一个即可(一般用于合并相同的常量字符串,减少重复数据占用的空间)。RODATA标志表示将变量定义在只读内存段,因此后续任何对此变量的修改操作将导致异常(recover也无法捕获)。NOPTR则表示此变量的内部不含指针数据,让垃圾回收器忽略对该变量的扫描。如果变量已经在Go代码中声明过的话,Go编译器会自动分析出该变量是否包含指针,这种时候可以不用手写NOPTR标志。
|
||||||
|
|
||||||
比如下面的例子是通过汇编来定义一个只读的int类型的变量:
|
比如下面的例子是通过汇编来定义一个只读的int类型的变量:
|
||||||
|
|
||||||
@ -359,9 +359,9 @@ GLOBL ·const_id(SB),NOPTR|RODATA,$8
|
|||||||
DATA ·const_id+0(SB)/8,$9527
|
DATA ·const_id+0(SB)/8,$9527
|
||||||
```
|
```
|
||||||
|
|
||||||
我们使用#include语句包含定义标志的"textflag.h"头文件(和C语言中预处理相同)。然后GLOBL汇编命令在定义变量时,给变量增加了NOPTR和RODATA两个标志(多个标志之间采用竖杠分割),表示变量中没有指针数据同时定义在只读代码段。
|
我们使用#include语句包含定义标志的"textflag.h"头文件(和C语言中预处理相同)。然后GLOBL汇编命令在定义变量时,给变量增加了NOPTR和RODATA两个标志(多个标志之间采用竖杠分割),表示变量中没有指针数据同时定义在只读数据段。
|
||||||
|
|
||||||
变量一般也叫可取地址的值,但是const_id虽然可以取地址,但是确实不能修改。不能修改的限制并不是由编译器提供,而是因为对该变量的修改会导致对只读内存段进行写导致,从而导致异常。
|
变量一般也叫可取地址的值,但是const_id虽然可以取地址,但是确实不能修改。不能修改的限制并不是由编译器提供,而是因为对该变量的修改会导致对只读内存段进行写,从而导致异常。
|
||||||
|
|
||||||
## 3.3.5 小结
|
## 3.3.5 小结
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ func NewKVStoreService() *KVStoreService {
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
func (p *KVStoreService) Get(key string, value *string) error {
|
func (p *KVStoreService) Get(key string, value *string) error {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
if v, ok := p.m[key]; ok {
|
if v, ok := p.m[key]; ok {
|
||||||
*value = v
|
*value = v
|
||||||
@ -108,8 +108,8 @@ func (p *KVStoreService) Get(key string, value *string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *KVStoreService) Set(kv [2]string, reply *struct{}) error {
|
func (p *KVStoreService) Set(kv [2]string, reply *struct{}) error {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
key, value := kv[0], kv[1]
|
key, value := kv[0], kv[1]
|
||||||
|
|
||||||
@ -133,9 +133,9 @@ func (p *KVStoreService) Watch(timeoutSecond int, keyChanged *string) error {
|
|||||||
id := fmt.Sprintf("watch-%s-%03d", time.Now(), rand.Int())
|
id := fmt.Sprintf("watch-%s-%03d", time.Now(), rand.Int())
|
||||||
ch := make(chan string, 10) // buffered
|
ch := make(chan string, 10) // buffered
|
||||||
|
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
p.filter[id] = func(key string) { ch <- key }
|
p.filter[id] = func(key string) { ch <- key }
|
||||||
p.Unlock()
|
p.mu.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Duration(timeoutSecond) * time.Second):
|
case <-time.After(time.Duration(timeoutSecond) * time.Second):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user