Merge pull request #78 from domainname/master

7.2、7.3、7.5、7.6几个章节的修改
This commit is contained in:
无闻
2015-03-16 05:07:05 -04:00
5 changed files with 22 additions and 20 deletions

View File

@@ -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** 下面代码段的输出是什么

View File

@@ -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后一个是剩余的用一行代码实现
## 链接

View File

@@ -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] {

View File

@@ -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

View File

@@ -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))
您还可以将一个字符串追加到某一个字符数组的尾部: