|
@@ -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 方法初始化;下图给出了区别:
|
|
换言之,new 方法分配内存,make 方法初始化;下图给出了区别:
|
|
|
|
|
|
|
@@ -199,7 +199,7 @@ make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的
|
|
|
|
|
|
|
|
在第二幅图中, `p := make([]int, 0)` ,slice 已经被初始化,但是指向一个空的数组。
|
|
在第二幅图中, `p := make([]int, 0)` ,slice 已经被初始化,但是指向一个空的数组。
|
|
|
|
|
|
|
|
-这两种方式实用性都不高,下面的方法:
|
|
|
|
|
|
|
+以上两种方式实用性都不高。下面的方法:
|
|
|
|
|
|
|
|
var v []int = make([]int, 10, 50)
|
|
var v []int = make([]int, 10, 50)
|
|
|
|
|
|
|
@@ -209,7 +209,7 @@ make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的
|
|
|
|
|
|
|
|
这样分配一个有 50 个 int 值的数组,并且创建了一个长度为 10,容量为 50 的 slice v,该 slice 指向数组的前 10 个元素。
|
|
这样分配一个有 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.4:假设 `s1 := []byte{'p', 'o', 'e', 'm'}` 且 `s2 := d[2:]`,s2 的值是多少?如果我们执行 `s2[1] == 't'`,s1 和 s2 现在的值又分配是多少?
|
|
|
|
|
|
|
|
## 7.2.5 多维 slice
|
|
## 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`
|
|
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
|
|
var buffer bytes.Buffer
|
|
|
for {
|
|
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,后一个是剩余的,用一行代码实现。
|
|
练习 7.6: 把一个缓存 buf 分片成两个 slice:第一个是前 n 个 bytes,后一个是剩余的,用一行代码实现。
|
|
|
|
|
|
|
|
## 链接
|
|
## 链接
|