diff --git a/README_gc.md b/README_gc.md index b25eaad..852ed87 100644 --- a/README_gc.md +++ b/README_gc.md @@ -9,13 +9,14 @@ 本书的主要译者是 [@无闻Unknwon](http://www.weibo.com/Obahua),是一名 Go 语言爱好者和传播者,目前是 [Go Walker](https://gowalker.org)、Gopm、[Gogs](http://gogs.io) 和 [Macaron](https://github.com/Unknwon/macaron) 创始人,极客学院签约讲师。 目前已由多位 Go 语言爱好者共同提交翻译内容,主要包括: - - [@zhanming](https://github.com/zhanming) - - themorecolor - - [@everyx](https://github.com/everyx) - - [@chidouhu](https://github.com/chidouhu) - - [@spawnris](https://github.com/spawnris) - - [@domainname](https://github.com/domainname) - - [@leisore](https://github.com/leisore) + +- [@zhanming](https://github.com/zhanming) +- themorecolor +- [@everyx](https://github.com/everyx) +- [@chidouhu](https://github.com/chidouhu) +- [@spawnris](https://github.com/spawnris) +- [@domainname](https://github.com/domainname) +- [@leisore](https://github.com/leisore) ## 适用人群 @@ -28,4 +29,4 @@ Golang 编程:245386165 |更新日期 |更新内容 |----------|------------------ -|2015-09-13|11.9 空接口 \ No newline at end of file +|2015-09-13|11.9 空接口 diff --git a/eBook/04.5.md b/eBook/04.5.md index 7abab04..20e6be2 100644 --- a/eBook/04.5.md +++ b/eBook/04.5.md @@ -474,7 +474,7 @@ var ch byte = 65 或 var ch byte = '\x41' (`\x` 总是紧跟着长度为 2 的 16 进制数) -另外一种可能的写法是 `\` 后面紧跟着长度为 3 的十进制数,例如:`\377`。 +另外一种可能的写法是 `\` 后面紧跟着长度为 3 的八进制数,例如:`\377`。 不过 Go 同样支持 Unicode(UTF-8),因此字符同样称为 Unicode 代码点或者 runes,并在内存中使用 int 来表示。在文档中,一般使用格式 U+hhhh 来表示,其中 h 表示一个 16 进制数。其实 `rune` 也是 Go 当中的一个类型,并且是 `int32` 的别名。 diff --git a/eBook/06.3.md b/eBook/06.3.md index 59510ef..dc1c37f 100644 --- a/eBook/06.3.md +++ b/eBook/06.3.md @@ -27,14 +27,14 @@ package main import "fmt" func main() { - x := Min(1, 3, 2, 0) + x := min(1, 3, 2, 0) fmt.Printf("The minimum is: %d\n", x) arr := []int{7,9,3,5,1} - x = Min(arr...) + x = min(arr...) fmt.Printf("The minimum in the array arr is: %d", x) } -func Min(a ...int) int { +func min(a ...int) int { if len(a)==0 { return 0 } diff --git a/eBook/06.4.md b/eBook/06.4.md index 800f8a7..1235ed0 100644 --- a/eBook/06.4.md +++ b/eBook/06.4.md @@ -11,17 +11,17 @@ package main import "fmt" func main() { - Function1() + function1() } -func Function1() { - fmt.Printf("In Function1 at the top\n") - defer Function2() - fmt.Printf("In Function1 at the bottom!\n") +func function1() { + fmt.Printf("In function1 at the top\n") + defer function2() + fmt.Printf("In function1 at the bottom!\n") } -func Function2() { - fmt.Printf("Function2: Deferred until the end of the calling function!") +func function2() { + fmt.Printf("function2: Deferred until the end of the calling function!") } ``` diff --git a/eBook/07.2.md b/eBook/07.2.md index 7ba6557..312a7d5 100644 --- a/eBook/07.2.md +++ b/eBook/07.2.md @@ -121,7 +121,7 @@ func sum(a []int) int { return s } -func main { +func main() { var arr = [5]int{0, 1, 2, 3, 4} sum(arr[:]) } @@ -226,7 +226,7 @@ v := make([]int, 10, 50) 这样分配一个有 50 个 int 值的数组,并且创建了一个长度为 10,容量为 50 的 切片 v,该 切片 指向数组的前 10 个元素。 **问题 7.3** 给定 `s := make([]byte, 5)`,len(s) 和 cap(s) 分别是多少?`s = s[2:4]`,len(s) 和 cap(s) 又分别是多少? -**问题 7.4** 假设 `s1 := []byte{'p', 'o', 'e', 'm'}` 且 `s2 := d[2:]`,s2 的值是多少?如果我们执行 `s2[1] == 't'`,s1 和 s2 现在的值又分配是多少? +**问题 7.4** 假设 `s1 := []byte{'p', 'o', 'e', 'm'}` 且 `s2 := s1[2:]`,s2 的值是多少?如果我们执行 `s2[1] = 't'`,s1 和 s2 现在的值又分别是多少? ## 7.2.5 多维 切片 diff --git a/eBook/07.5.md b/eBook/07.5.md index 5014788..92d9a19 100644 --- a/eBook/07.5.md +++ b/eBook/07.5.md @@ -44,7 +44,7 @@ func AppendByte(slice []byte, data ...byte) []byte { } ``` -`func copy(dst, src []T) int` copy 方法将类型为 T 的切片从源地址 src 拷贝到目标地址 dst,覆盖 dst 的相关元素,并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是 src 和 dst 的长度最小值。如果 src 是字符串那么元素类型就是 byte。如果你还想继续使用 src,在拷贝技术后执行 `src = dst`。 +`func copy(dst, src []T) int` copy 方法将类型为 T 的切片从源地址 src 拷贝到目标地址 dst,覆盖 dst 的相关元素,并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是 src 和 dst 的长度最小值。如果 src 是字符串那么元素类型就是 byte。如果你还想继续使用 src,在拷贝结束后执行 `src = dst`。 **练习 7.9** diff --git a/eBook/08.1.md b/eBook/08.1.md index e860492..edcc530 100644 --- a/eBook/08.1.md +++ b/eBook/08.1.md @@ -27,7 +27,7 @@ map 也可以用函数作为自己的值,这样就可以用来做分支结构 key1 对应的值可以通过赋值符号来设置为 `val1:map1[key1] = val1`。 -令 `v: = map1[key1]` 可以将 key1 对应的值赋值为 v;如果 map 中没有 key1 存在,那么 v 将被赋值为 map1 的值类型的空值。 +令 `v := map1[key1]` 可以将 key1 对应的值赋值为 v;如果 map 中没有 key1 存在,那么 v 将被赋值为 map1 的值类型的空值。 常用的 `len(map1)` 方法可以获得 map 中的 pair 数目,这个数目是可以伸缩的,因为 map-pairs 在运行时可以动态添加和删除。 diff --git a/eBook/08.5.md b/eBook/08.5.md index d404b1d..495345a 100644 --- a/eBook/08.5.md +++ b/eBook/08.5.md @@ -53,7 +53,7 @@ func main() { 但是如果你想要一个排序的列表你最好使用结构体切片,这样会更有效: ```go -type struct { +type name struct { key string value int } diff --git a/eBook/08.6.md b/eBook/08.6.md index 004c618..3daef1b 100644 --- a/eBook/08.6.md +++ b/eBook/08.6.md @@ -26,7 +26,6 @@ func main() { for k, v := range invMap { fmt.Printf("Key: %v, Value: %v / ", k, v) } - fmt.Println() } ``` diff --git a/eBook/09.5.md b/eBook/09.5.md old mode 100755 new mode 100644 diff --git a/eBook/09.8.md b/eBook/09.8.md old mode 100755 new mode 100644 diff --git a/eBook/10.8.md b/eBook/10.8.md index 4781493..b5ceedc 100644 --- a/eBook/10.8.md +++ b/eBook/10.8.md @@ -7,7 +7,11 @@ Go 开发者不需要写代码来释放程序中不再使用的变量和结构 如果想知道当前的内存状态,可以使用: ```go -fmt.Printf("%d\n", runtime.MemStats.Alloc/1024) +// fmt.Printf("%d\n", runtime.MemStats.Alloc/1024) +// 此处代码在 Go 1.5.1下不再有效,更正为 +var m runtime.MemStats +runtime.ReadMemStats(&m) +fmt.Printf("%d Kb\n", m.Alloc / 1024) ``` 上面的程序会给出已分配内存的总量,单位是 Kb。进一步的测量参考 [文档页面](http://golang.org/pkg/runtime/#MemStatsType)。 @@ -30,4 +34,4 @@ runtime.SetFinalizer(obj, func(obj *typeObj)) - [目录](directory.md) - 上一节:[类型的 String() 方法和格式化描述符](10.7.md) -- 下一章:[接口(Interfaces)与反射(reflection)](11.0.md) \ No newline at end of file +- 下一章:[接口(Interfaces)与反射(reflection)](11.0.md) diff --git a/eBook/11.11.md b/eBook/11.11.md new file mode 100644 index 0000000..c520718 --- /dev/null +++ b/eBook/11.11.md @@ -0,0 +1,68 @@ +# 11.11 Printf和反射 + +在Go语言的标准库中,前几节所述的反射的功能被大量地使用。举个例子,fmt包中的Printf(以及其他格式化输出函数)都会使用反射来分析它的`...`参数。 + +Printf的函数声明为: + +```go +func Printf(format string, args ... interface{}) (n int, err error) +``` + +Printf中的`...`参数为空接口类型。Printf使用反射包来解析这个参数列表。所以,Printf能够知道它每个参数的类型。因此格式化字符串中只有%d而没有%u和%ld,因为它知道这个参数是unsigned还是long。这也是为什么Print和Println在没有格式字符串的情况下还能如此漂亮地输出。 + +为了让大家更加具体地了解Printf中的反射,我们实现了一个简单的通用输出函数。其中使用了type-switch来推导参数类型,并根据类型来输出每个参数的值(这里用了10.7节中练习10.13的部分代码) + +示例 11.15 print.go: +```go +// print.go +package main + +import ( + "os" + "strconv" +) + +type Stringer interface { + String() string +} + +type Celsius float64 + +func (c Celsius) String() string { + return strconv.FormatFloat(float64(c),'f', 1, 64) + " °C" +} + +type Day int + +var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} + +func (day Day) String() string { + return dayName[day] +} + +func print(args ...interface{}) { + for i, arg := range args { + if i > 0 {os.Stdout.WriteString(" ")} + switch a := arg.(type) { // type switch + case Stringer: os.Stdout.WriteString(a.String()) + case int: os.Stdout.WriteString(strconv.Itoa(a)) + case string: os.Stdout.WriteString(a) + // more types + default: os.Stdout.WriteString("???") + } + } +} + +func main() { + print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C +} +// Tuesday was 18.4 °C +``` + +在12.8节中我们将阐释fmt.Fprintf()是怎么运用同样的反射原则的。 + +## 链接 + +- [目录](directory.md) +- 上一节:[反射包](11.10.md) +- 下一节:[接口和动态类型](11.12.md) diff --git a/12.6.md b/eBook/12.6.md similarity index 100% rename from 12.6.md rename to eBook/12.6.md