Prechádzať zdrojové kódy

Merge pull request #78 from domainname/master

7.2、7.3、7.5、7.6几个章节的修改
无闻 11 rokov pred
rodič
commit
911e32c934
5 zmenil súbory, kde vykonal 22 pridanie a 20 odobranie
  1. 2 2
      eBook/07.1.md
  2. 12 10
      eBook/07.2.md
  3. 3 3
      eBook/07.3.md
  4. 1 1
      eBook/07.5.md
  5. 4 4
      eBook/07.6.md

+ 2 - 2
eBook/07.1.md

@@ -26,7 +26,7 @@ arr1 的长度是 5,索引范围从 0 到 len(arr1)-1
 
 	runtime error: index out of range
 
-由于索引的存在,遍历数组的方法自然就是使用 for 语句:
+由于索引的存在,遍历数组的方法自然就是使用 for 结构:
 
 - 通过 for 初始化数组项
 - 通过 for 打印数组元素
@@ -73,7 +73,7 @@ IDIOM:
 	...
 	}
 
-在这里i也是数组的索引。当然这两种 for 语句对于切片(slices)(参考 [第 7 章](07.2.md))来说也同样适用。
+在这里i也是数组的索引。当然这两种 for 结构对于切片(slices)(参考 [第 7 章](07.2.md))来说也同样适用。
 
 **问题 7.1** 下面代码段的输出是什么?
 

+ 12 - 10
eBook/07.2.md

@@ -184,9 +184,9 @@ make 的使用方式是:`func make([]T, len, cap)` 其中 cap 是可选参数
 
 看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型。
 
-new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回内存地址,类型 *T:这种方法 **返回一个指向类型为 T,值为 0 的地址的指针**,它适用于值类型如数组和结构体(参见第 10 章);它相当于 `&T{}`。
+* new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为\*T的内存地址:这种方法**返回一个指向类型为 T,值为 0 的地址的指针**,它适用于值类型如数组和结构体(参见第 10 章);它相当于 `&T{}`。
 
-make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的引用类型:slice, map 和 channel(参见第 8 章,第 13 章)
+* make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的引用类型:slice, map 和 channel(参见第 8 章,第 13 章)
 
 换言之,new 方法分配内存,make 方法初始化;下图给出了区别:
 
@@ -199,7 +199,7 @@ make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的
 
 在第二幅图中, `p := make([]int, 0)` ,slice 已经被初始化,但是指向一个空的数组。
 
-这两种方式实用性都不高,下面的方法:
+以上两种方式实用性都不高。下面的方法:
 
 	var v []int = make([]int, 10, 50)
 
@@ -209,7 +209,7 @@ make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的
 
 这样分配一个有 50 个 int 值的数组,并且创建了一个长度为 10,容量为 50 的 slice v,该 slice 指向数组的前 10 个元素。
 
-问题 7.3:给定 `s := make([]byte, 5)`,len(s) 和 cap(s) 分别是多少?`s = s[2:4]`,len(s) 和 cap(s) 又分别是多少?
+问题 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.2.5 多维 slice
@@ -227,17 +227,19 @@ bytes 包和字符串包十分类似(参见第 4.7 节)。而且它还包含
 		...
 	}
 
-这是一个 bytes 的定长 buffer,提供 Read 和 Write 方法,因为读写不知道长度的 bytes 最好使用 buffer。
+这是一个长度可变的 bytes 的 buffer,提供 Read 和 Write 方法,因为读写长度未知的 bytes 最好使用 buffer。
 
 Buffer 可以这样定义:`var buffer bytes.Buffer`
 
-或者 new 出一个指针:`var r *bytes.Buffer = new(bytes.Buffer)`
+或者使用 new 获得一个指针:`var r *bytes.Buffer = new(bytes.Buffer)`
 
-或者通过函数:`func NewBuffer(buf []byte) *Buffer`,这就用创建一个 Buffer 对象并且用 buf 初始化好;NewBuffer 最好用在从 buf 读取的时候使用。
+或者通过函数:`func NewBuffer(buf []byte) *Buffer`,创建一个 Buffer 对象并且用 buf 初始化好;NewBuffer 最好用在从 buf 读取的时候使用。
 
-通过 buffer 串联字符串:类似于 Java 的 StringBuilder 类。
+**通过 buffer 串联字符串**
 
-创建一个 Buffer,通过 buffer.WriteString(s) 方法将每个 string s 追加到后面,最后再通过 buffer.String() 方法转换为 string,下面是代码段:
+类似于 Java 的 StringBuilder 类。
+
+在下面的代码段中,我们创建一个 buffer,通过 buffer.WriteString(s) 方法将字符串 s 追加到后面,最后再通过 buffer.String() 方法转换为 string:
 
 	var buffer bytes.Buffer
 	for {
@@ -253,7 +255,7 @@ Buffer 可以这样定义:`var buffer bytes.Buffer`
 
 练习:
 
-练习 7.5: 给定 slice sl,将 a []byte 数组追加到 sl 后面。写一个函数 `Append(slice, data []byte) []byte`,该函数在 sl 不能存储更多数据的时候自动扩容。
+练习 7.5: 给定 slice sl,将 a []byte 数组追加到 sl 后面。写一个函数 `Append(slice, data []byte) []byte`,该函数在 sl 不能存储更多数据的时候自动扩容。  
 练习 7.6: 把一个缓存 buf 分片成两个 slice:第一个是前 n 个 bytes,后一个是剩余的,用一行代码实现。
 
 ## 链接

+ 3 - 3
eBook/07.3.md

@@ -6,7 +6,7 @@
 		...
 	}
 
-第一个返回值 dx 是数组或者 slice 的索引,第二个是在该索引位置的值;他们都是仅在 for 循环内部可见的局部变量,所以该值只是该索引项 slice 值的一个拷贝并且不能被修改
+第一个返回值 dx 是数组或者 slice 的索引,第二个是在该索引位置的值;他们都是仅在 for 循环内部可见的局部变量。value 只是 slice1 某个索引位置的值的一个拷贝,不能用来修改 slice1 该索引位置的值
 
 示例 7.9 [slices_forrange.go](examples/chapter_7/slices_forrange.go)
 
@@ -53,9 +53,9 @@ slices_forrange2.go 给出了一个关于字符串的例子, `_` 可以用于
 
 如果你需要修改 seasons[ix] 的值可以使用这个版本。
 
-多维 slice 下的 for-range 方法
+**多维 slice 下的 for-range:**
 
-通过计算行数和矩阵值可以很方便的写出如(参考第 7.1.3 节)的 for-loops 方法来,例如(参考第 7.5 节的例子 multidim_array.go):
+通过计算行数和矩阵值可以很方便的写出如(参考第 7.1.3 节)的 for 循环来,例如(参考第 7.5 节的例子 multidim_array.go):
 
 	for row := range screen {
 		for column := range screen[0] {

+ 1 - 1
eBook/07.5.md

@@ -31,7 +31,7 @@ func AppendByte(slice []byte, data ...byte) []byte {
 	m := len(slice)
 	n := m + len(data)
 	if n > cap(slice) { // if necessary, reallocate
-		// allocate doublke what's needed, for future growth.
+		// allocate double what's needed, for future growth.
 		newSlice := make([]byte, (n+1)*2)
 		copy(newSlice, slice)
 		slice = newSlice

+ 4 - 4
eBook/07.6.md

@@ -2,9 +2,9 @@
 
 ## 7.6.1 从字符串生成字节切片
 
-假设 s 是一个字符串(本质上是一个字节数组),那么就可以直接通过 `c := []bytes(s)` 来获取 c 为一个元素类型为字节的切片。另外,您还可以通过 copy 函数来实现:`copy(dst []byte, src string)`.
+假设 s 是一个字符串(本质上是一个字节数组),那么就可以直接通过 `c := []bytes(s)` 来获取一个字节的切片 c。另外,您还可以通过 copy 函数来达到相同的目的:`copy(dst []byte, src string)`。
 
-同样的,还可以使用 for-range 语法来获得每个元素(Listing 7.13—for_string.go):
+同样的,还可以使用 for-range 来获得每个元素(Listing 7.13—for_string.go):
 
 ```go
 package main
@@ -23,9 +23,9 @@ func main() {
 
     0:ÿ 2:界
 
-我们发现,Unicode 字符会占用 2 个字节,有些甚至需要 3 个或者 4 个字节来进行表示。如果发现错误的 UTF8 字符,则该字符会被设置为 U+FFFD 并直接向前移动一个字节。和字符串转换一样,您同样可以使用 `c := []int(s)` 语法,这样切片中的每个 int 都会包含对应的 Unicode 代码,因为字符串中的每次字符都会对应一个整数。类似的,您也可以将字符串转换为元素类型为 rune 的切片:`r := []rune(s)`。
+我们知道,Unicode 字符会占用 2 个字节,有些甚至需要 3 个或者 4 个字节来进行表示。如果发现错误的 UTF8 字符,则该字符会被设置为 U+FFFD 并且索引向前移动一个字节。和字符串转换一样,您同样可以使用 `c := []int(s)` 语法,这样切片中的每个 int 都会包含对应的 Unicode 代码,因为字符串中的每次字符都会对应一个整数。类似的,您也可以将字符串转换为元素类型为 rune 的切片:`r := []rune(s)`。
 
-可以通过代码 `len([]int(s))` 来获得字符串中字符的数量,但使用 `utf8.RuneCountInString(s)` 效率会更高一点。
+可以通过代码 `len([]int(s))` 来获得字符串中字符的数量,但使用 `utf8.RuneCountInString(s)` 效率会更高一点。(参考[count_characters.go](exercises/chapter_4/count_characters.go))
 
 您还可以将一个字符串追加到某一个字符数组的尾部: