mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-11 22:06:51 +08:00
@@ -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** 下面代码段的输出是什么?
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
@@ -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] {
|
||||
|
@@ -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
|
||||
|
@@ -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))
|
||||
|
||||
您还可以将一个字符串追加到某一个字符数组的尾部:
|
||||
|
||||
|
Reference in New Issue
Block a user