PRF:20180712 Slices from the ground up.md

@pityonline
This commit is contained in:
Xingyu.Wang 2018-08-19 22:15:02 +08:00
parent 4d4f007560
commit f234a54890

View File

@ -23,14 +23,14 @@
}
```
语句 `b := a` 定义了一个类型是 `[5]int` 的新变量 `b`,然后把 `a` 中的内容 _复制_`b` 中。改变 `b``a` 中的内容没有影响,因为 `a``b` 是相互独立的值。^1
语句 `b := a` 定义了一个类型是 `[5]int` 的新变量 `b`,然后把 `a` 中的内容 _复制_`b` 中。改变 `b``a` 中的内容没有影响,因为 `a``b` 是相互独立的值。[^1]
### 切片
Go 语言的切片和数组的主要有如下两个区别:
1. 切片没有一个固定的长度。切片的长度不是它类型定义的一部分,而是由切片内部自己维护的。我们可以使用内置的 `len` 函数知道它的长度。^2
2. 将一个切片赋值给另一个切片时 _不会_ 对切片内容进行复制操作。这是因为切片没有直接持有其内部数据,而是保留了一个指向 _底层数组_ ^3 的指针。数据都保留在底层数组里。
1. 切片没有一个固定的长度。切片的长度不是它类型定义的一部分,而是由切片内部自己维护的。我们可以使用内置的 `len` 函数知道它的长度。[^2]
2. 将一个切片赋值给另一个切片时 _不会_ 对切片内容进行复制操作。这是因为切片没有直接持有其内部数据,而是保留了一个指向 _底层数组_ [^3] 的指针。数据都保留在底层数组里。
基于第二个特性,两个切片可以享有共同的底层数组。看下面的示例:
@ -99,7 +99,7 @@ irb(main):004:0> a
=> [1, 2, 0, 4, 5]
```
在大多数将数组视为对象或者是引用类型的语言也是如此。^4
在大多数将数组视为对象或者是引用类型的语言也是如此。[^4]
### 切片头
@ -155,7 +155,7 @@ func main() {
}
```
Go 的切片是作为值传递而不是指针这一点不太寻常。当你在 Go 内定义一个结构体时90% 的时间里传递的都是这个结构体的指针^5 。切片的传递方式真的很不寻常,我能想到的唯一与之相同的例子只有 `time.Time`
Go 的切片是作为值传递而不是指针这一点不太寻常。当你在 Go 内定义一个结构体时90% 的时间里传递的都是这个结构体的指针[^5] 。切片的传递方式真的很不寻常,我能想到的唯一与之相同的例子只有 `time.Time`
切片作为值传递而不是作为指针传递这一特殊行为会让很多想要理解切片的工作原理的 Go 程序员感到困惑。你只需要记住,当你对切片进行赋值、取切片、传参或者作为返回值等操作时,你是在复制切片头结构的三个字段:指向底层数组的指针、长度,以及容量。
@ -193,7 +193,7 @@ level: 1 slice: [0 1]
level: 0 slice: [0]
```
你可以注意到在每一个 `level``s` 的值没有被别的 `f` 的调用影响,尽管当计算更高的 `level` 时作为 `append` 的副产品,调用栈内的四个 `f` 函数创建了四个底层数组^6 ,但是没有影响到当前各自的切片。
你可以注意到在每一个 `level``s` 的值没有被别的 `f` 的调用影响,尽管当计算更高的 `level` 时作为 `append` 的副产品,调用栈内的四个 `f` 函数创建了四个底层数组[^6] ,但是没有影响到当前各自的切片。
### 扩展阅读
@ -202,14 +202,12 @@ level: 0 slice: [0]
* [Go Slices: usage and internals][5] (blog.golang.org)
* [Arrays, slices (and strings): The mechanics of 'append'][6] (blog.golang.org)
### 注释
- 注1这不是数组才有的特性在 Go 语言里中 _一切_ 赋值都是复制过去的。
- 注2你也可以在对数组使用 `len` 函数,但是其结果本来就人尽皆知。
- 注3有时也叫做<ruby>后台数组<rt>backing array</rt></ruby>,以及更不严谨的说法是后台切片。
- 注4Go 语言里我们倾向于说值类型以及指针类型,因为 C++ 的<ruby>引用<rt>reference</rt></ruby>类型这个词产生误会。但在这里我认为调用数组作为引用类型是没有问题的。
- 注5如果你的结构体有[定义在其上的方法或者用于满足某个接口][7],那么你传入结构体指针的比率可以飙升到接近 100%。
-注 6证明留做习题。
[^1]: 这不是数组才有的特性,在 Go 语言里中 _一切_ 赋值都是复制过去的。
[^2]: 你也可以在对数组使用 `len` 函数,但是其结果本来就人尽皆知。
[^3]: 有时也叫做<ruby>后台数组<rt>backing array</rt></ruby>,以及更不严谨的说法是后台切片。
[^4]: Go 语言里我们倾向于说值类型以及指针类型,因为 C++ 的<ruby>引用<rt>reference</rt></ruby>类型这个词产生误会。但在这里我认为调用数组作为引用类型是没有问题的。
[^5]: 如果你的结构体有[定义在其上的方法或者用于满足某个接口][7],那么你传入结构体指针的比率可以飙升到接近 100%。
[^6]: 证明留做习题。
### 相关文章: