Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c9fc5db

Browse files
RickyWang1020Tinywan
authored andcommitted
Update golang_tutorial_11.md
1 parent 41f3e38 commit c9fc5db

File tree

1 file changed

+34
-34
lines changed

1 file changed

+34
-34
lines changed

‎docs/golang_tutorial_11.md‎

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
数组是类型相同的元素的集合。例如,整数 5, 8, 9, 79, 76 的集合就构成了一个数组。Go不允许在数组中混合使用不同类型的元素(比如整数和字符串)。
1212

13-
## 申明
13+
## 声明
1414

1515
数组的类型为` [n]T`,其中 `n` 表示数组中元素的个数,`T` 表示数组中元素的类型。元素的个数 `n`也是数组类型的一部分(我们将在稍后详细讨论)。
1616

@@ -51,9 +51,9 @@ func main() {
5151

5252
`a[0]`表示数组中的第一个元素。程序的输出为:`[12 78 50]`
5353

54-
(译者注:可以用下标运算符(`[]`)来访问数组中的元素,下标从 0 开始,例如 `a[0]` 表示数组 a 的第一个元素,`a[1]`表示数组 a 的第二元素,以此类推。)
54+
(译者注:可以用下标运算符(`[]`)来访问数组中的元素,下标从 0 开始,例如 `a[0]` 表示数组 a 的第一个元素,`a[1]`表示数组 a 的第二个元素,以此类推。)
5555

56-
可以利用**速记声明(shorthand declaration)**的方式来创建同样的数组:
56+
可以利用**速记声明(shorthand declaration)**的方式来创建同样的数组:
5757

5858
```golang
5959
package main
@@ -87,7 +87,7 @@ func main() {
8787
}
8888
```
8989

90-
上面程序的第 8 行:`a := [3]int{12}`声明了一个长度为 3 的数组,但是只提供了一个初值 12。剩下的两个元素被自动赋值为 0。程序 的输出为:`[12 0 0]`
90+
上面程序的第 8 行:`a := [3]int{12}`声明了一个长度为 3 的数组,但是只提供了一个初值 12。剩下的两个元素被自动赋值为 0。程序 的输出为:`[12 0 0]`
9191

9292
在声明数组时你可以忽略数组的长度并用` ... `代替,让编译器为你自动推导数组的长度。比如下面的程序:
9393

@@ -104,7 +104,7 @@ func main() {
104104
}
105105
```
106106

107-
上面已经提到,数组的长度是数组类型的一部分。因此 `[5]int``[25]int`是两个不同类型的数组。正是因为如此,一个数组不能动态改变长度。不要担心这个限制,因为切片(`slices`)可以弥补这个不足。
107+
上面已经提到,数组的长度是数组类型的一部分。因此 `[5]int``[25]int`是两个不同类型的数组。正是因为如此,一个数组不能动态改变长度。不要担心这个限制,因为切片(`slices`)可以弥补这个不足。
108108

109109
```golang
110110
package main
@@ -116,7 +116,7 @@ func main() {
116116
}
117117
```
118118

119-
在上面程序的第 6 行,我们试图将一个`[3]int`类型的数组赋值给一个 `[5]int`类型的数组,这是不允许的。编译会报错:`main.go:6: cannot use a (type [3]int) as type [5]int in assignment。`
119+
在上面程序的第 6 行,我们试图将一个`[3]int`类型的数组赋值给一个 `[5]int`类型的数组,这是不允许的。编译会报错:`main.go:6: cannot use a (type [3]int) as type [5]int in assignment。`
120120

121121
## 数组是值类型
122122

@@ -189,7 +189,7 @@ func main() {
189189

190190
## 使用 range 遍历数组
191191

192-
`for`循环可以用来遍历数组中的元素:
192+
`for`循环可以用来遍历数组中的元素:
193193

194194
```golang
195195
package main
@@ -212,7 +212,7 @@ func main() {
212212
3 th element of a is 78.00
213213
```
214214

215-
Go 提供了一个更简单,更简洁的遍历数组的方法:使用 `range for`range 返回数组的索引和索引对应的值。让我们用 range for 重写上面的程序(除此之外我们还计算了数组元素的总和)。
215+
Go 提供了一个更简单,更简洁的遍历数组的方法:使用 range 形式的 for 循环。`range` 返回数组的索引和索引对应的值。让我们用 range for 重写上面的程序(除此之外我们还计算了数组元素的总和)。
216216
```golang
217217
package main
218218

@@ -247,7 +247,7 @@ for _, v := range a { //ignores index
247247
}
248248
```
249249

250-
上面的代码忽略了索引。同样的,也可以忽略值。
250+
上面的代码忽略了索引。用类似的方法,也可以忽略值。
251251

252252
## 多维数组
253253

@@ -288,7 +288,7 @@ func main() {
288288
}
289289
```
290290

291-
上面的程序中,第 17 行利用速记声明创建了一个二维数组 a。第 20 行的逗号是必须的,这是因为词法分析器会根据一些简单的规则自动插入分号。如果你想了解更多,请阅读:https://golang.org/doc/effective_go.html#semicolons
291+
上面的程序中,第 17 行利用速记声明创建了一个二维数组 a。第 20 行的逗号是必须的,因为词法分析器会根据一些简单的规则自动插入分号。如果你想了解更多,请阅读:https://golang.org/doc/effective_go.html#semicolons
292292

293293
在第 23 行声明了另一个二维数组 b,并通过索引的方式给数组 b 中的每一个元素赋值。这是初始化二维数组的另一种方式。
294294

@@ -312,7 +312,7 @@ AT&T T-Mobile
312312

313313
## 创建切片
314314

315-
元素类型为 `T`的切片表示为: `[]T`
315+
元素类型为 `T`的切片表示为: `[]T`
316316

317317
```golang
318318
package main
@@ -328,7 +328,7 @@ func main() {
328328
}
329329
```
330330

331-
通过 `a[start:end]`这样的语法创建了一个从`a[start]``a[end -1]` 的切片。在上面的程序中,第 9 行`a[1:4]` 创建了一个从 `a[1]``a[3]` 的切片。因此 b 的值为:`[77 78 79]`
331+
通过 `a[start:end]`这样的语法创建了一个从`a[start]``a[end -1]` 的切片。在上面的程序中,第 9 行`a[1:4]` 创建了一个从 `a[1]``a[3]` 的切片。因此 b 的值为:`[77 78 79]`
332332

333333
下面是创建切片的另一种方式:
334334

@@ -345,7 +345,7 @@ func main() {
345345
}
346346
```
347347

348-
在上面的程序中,第 9 行 `c := []int{6, 7, 8}`创建了一个长度为 3 的 int 数组,并返回一个切片给 c。
348+
在上面的程序中,第 9 行 `c := []int{6, 7, 8}`创建了一个长度为 3 的 int 数组,并返回一个切片给 c。
349349

350350
## 修改切片
351351

@@ -397,7 +397,7 @@ func main() {
397397
}
398398
```
399399

400-
可以看到,在第 9 行,`numa[:]`中缺少了开始和结束的索引值,这种情况下开始和结束的索引值默认为 `0``len(numa)`。这里 `nums1``nums2` 共享了同一个数组。程序的输出为:
400+
可以看到,在第 9 行,`numa[:]`中缺少了开始和结束的索引值,这种情况下开始和结束的索引值默认为 `0``len(numa)`。这里 `nums1``nums2` 共享了同一个数组。程序的输出为:
401401

402402
```golang
403403
array before change 1 [78 79 80]
@@ -429,11 +429,11 @@ func main() {
429429
}
430430
```
431431

432-
在上面的程序中,创建了一个以 fruitarray 为底层数组,索引从 1 到 3 的切片 `fruitslice`因此 fruitslice 长度为 2。
432+
在上面的程序中,创建了一个以 `fruitarray` 为底层数组,索引从 1 到 2 的切片 `fruitslice`,因此 fruitslice 长度为 2。
433433

434-
`fruitarray` 的长度是 7。`fruiteslice` 是从 `fruitarray` 的索引 1 开始的。因此 `fruiteslice` 的容量是从 `fruitarray` 的第 1 个元素开始算起的数组中的元素个数,这个值是 6。因此 `fruitslice` 的容量是 6。程序的输出为:`length of slice 2 capacity 6`
434+
`fruitarray` 的长度是 7。`fruiteslice` 是从 `fruitarray` 的索引 1 开始的。因此 `fruiteslice` 的容量是从 `fruitarray` 的第 1 个元素开始算起的数组中的元素个数,这个值是 6。因此 `fruitslice` 的容量是 6。程序的输出为:`length of slice 2 capacity 6`
435435

436-
切片的长度可以动态的改变(最大为其容量)。任何超出最大容量的操作都会发生运行时错误
436+
切片的长度可以动态地改变(最大长度为其容量)。任何超出切片容量的操作都会发生运行错误
437437

438438
```golang
439439
package main
@@ -460,7 +460,7 @@ After re-slicing length is 6 and capacity is 6
460460

461461
## 用 make 创建切片
462462

463-
内置函数`func make([]T, len, cap) []T` 可以用来创建切片,该函数接受**长度****容量**作为参数,返回切片。容量是可选的,默认与长度相同。使用 make 函数将会创建一个数组并返回它的切片。
463+
内置函数`func make([]T, len, cap) []T` 可以用来创建切片,该函数接受**长度****容量**作为参数,返回切片。容量是可选的,默认与长度相同。使用 make 函数将会创建一个数组并返回它的切片。
464464

465465
```golang
466466
package main
@@ -483,7 +483,7 @@ func main() {
483483

484484
`x ...T` 表示 append 函数可以接受的参数个数是可变的。这种函数叫做变参函数。
485485

486-
你可能会问一个问题:如果切片是建立在数组之上的,而数组本身不能改变长度,那么切片是如何动态改变长度的呢?实际发生的情况是,当新元素通过调用 append 函数追加到切片末尾时,如果超出了容量,append 内部会创建一个新的数组。并将原有数组的元素被拷贝给这个新的数组,最后返回建立在这个新数组上的切片。这个新切片的容量是旧切片的二倍(译者注:当超出切片的容量时,append 将会在其内部创建新的数组,该数组的大小是原切片容量的 2 倍。最后 append 返回这个数组的全切片,即从 0 到 length - 1 的切片)。下面的程序使事情变得明朗:
486+
你可能会问一个问题:如果切片是建立在数组之上的,而数组本身不能改变长度,那么切片是如何动态改变长度的呢?实际发生的情况是,当新元素通过调用 append 函数追加到切片末尾时,如果超出了容量,append 内部会创建一个新的数组。并将原有数组的元素拷贝给这个新的数组,最后返回建立在这个新数组上的切片。这个新切片的容量是旧切片的二倍(译者注:当超出切片的容量时,append 将会在其内部创建新的数组,该数组的大小是原切片容量的 2 倍。最后 append 返回这个数组的全切片,即从 0 到 length - 1 的切片)。下面的程序会帮助你理解这一知识点:
487487

488488
```golang
489489
package main
@@ -500,7 +500,7 @@ func main() {
500500
}
501501
```
502502

503-
在上面的程序中,cars 的容量开始时为 3。在第 10 行我们追加了一个新的元素给 `cars`,并将 `append(cars, "Toyota")`的返回值重新复制给 cars。现在 cars 的容量翻倍,变为 6。上面的程序输出为:
503+
在上面的程序中,cars 的容量开始时为 3。在第 10 行我们追加了一个新的元素给 `cars`,并将 `append(cars, "Toyota")`的返回值重新复制给 cars。现在 cars 的容量翻倍,变为 6。上面的程序输出为:
504504

505505
```golang
506506
cars: [Ferrari Honda Ford] has old length 3 and capacity 3
@@ -588,7 +588,7 @@ func main() {
588588
}
589589
```
590590

591-
在上面的程序中,第 17 行将切片中的每个元素的值减2。在函数调用之后打印切片的的内容,发现切片内容发生了改变。你可以回想一下,这不同于一个数组,对函数内部的数组所做的更改在函数外不可见。上面的程序输出如下:
591+
在上面的程序中,第 17 行将切片中的每个元素的值减 2。在函数调用之后打印切片的的内容,发现切片内容发生了改变。你可以回想一下,这不同于一个数组,对函数内部的数组所做的更改在函数外不可见。上面的程序输出如下:
592592

593593
```golang
594594
array before function call [8 7 6]
@@ -634,7 +634,7 @@ Go Rust
634634

635635
切片保留对底层数组的引用。只要切片存在于内存中,数组就不能被垃圾回收。这在内存管理方便可能是值得关注的。假设我们有一个非常大的数组,而我们只需要处理它的一小部分,为此我们创建这个数组的一个切片,并处理这个切片。这里要注意的事情是,数组仍然存在于内存中,因为切片正在引用它。
636636

637-
解决该问题的一个方法是使用 copy 函数 `func copy(dst, src []T) int`来创建该切片的一个拷贝。这样我们就可以使用这个新的切片,原来的数组可以被垃圾回收。
637+
解决该问题的一个方法是使用 copy 函数 `func copy(dst, src []T) int`来创建该切片的一个拷贝。这样我们就可以使用这个新的切片,原来的数组可以被垃圾回收。
638638

639639
```golang
640640
package main
@@ -656,7 +656,7 @@ func main() {
656656
}
657657
```
658658

659-
在上面程序中,第 9 行 `neededCountries := countries[:len(countries)-2]`创建一个底层数组为 `countries` 并排除最后两个元素的切片。第 11 行将 `neededCountries` 拷贝到 `countriesCpy` 并在下一行返回 `countriesCpy`。现在数组 `countries` 可以被垃圾回收,因为 `neededCountries` 不再被引用。
659+
在上面程序中,第 9 行 `neededCountries := countries[:len(countries)-2]`创建一个底层数组为 `countries` 并排除最后两个元素的切片。第 11 行将 `neededCountries` 拷贝到 `countriesCpy` 并在下一行返回 `countriesCpy`。现在数组 `countries` 可以被垃圾回收,因为 `neededCountries` 不再被引用。
660660

661661
我(原文作者)已经将我们讨论的所有概念汇总到一个程序中,你可以从 [github](https://github.com/golangbot/arraysandslices) 下载。
662662

@@ -666,9 +666,9 @@ func main() {
666666
[深入解析 Go 中 Slice 底层实现](https://halfrost.com/go_slice/)
667667
###### 创建(定义)数组
668668
数组在Go中是值类型,而不是引用(其他语言的数组则是引用类型)
669-
PS:切片(slice)是一个引用类型
670-
数组不是统一的类型,大小不同的数组是不可以比较的
671-
不同数组类型是不可以比较的
669+
670+
PS:切片(slice)是一个引用类型。数组不是统一的类型,大小不同的数组是不可以比较的,不同数组类型是不可以比较的
671+
672672
```golang
673673
var a[2]int
674674
var b[3]string
@@ -689,9 +689,9 @@ var d = [...]int{19:90} // 尽可能的满足索引值得数组
689689
a := [...]int{19:100}
690690

691691
// 指向数组的指针
692-
var p *[20]int = &a //长度为20的int型数组,这里的数组长度`20`必须和a数组长度相等
692+
var p *[20]int = &a //长度为20的int型数组,这里的数组长度`20`必须和a数组长度相等
693693
fmt.Println(p) //以上表示取这样一个数组的地址
694-
// 打印结果:&[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19]
694+
// 打印结果:&[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100]
695695

696696
//指向指针的数组
697697
x , y := 1, 2
@@ -702,7 +702,7 @@ fmt.Println("pp is ",pp) // 打印结果:pp is [0xc420012128 0xc420012130]
702702

703703
```golang
704704
ppp := new([10]int)
705-
fmt.Println("----ppp-------",ppp); //输出结果:`&[0 0 0 0 0 0 0 0 0 0]`
705+
fmt.Println("----ppp-------",ppp); //输出结果:`----ppp------- &[0 0 0 0 0 0 0 0 0 0]`
706706
//以上为指向数组的指针
707707
```
708708

@@ -712,12 +712,12 @@ fmt.Println("----ppp-------",ppp); //输出结果:`&[0 0 0 0 0 0 0 0 0 0]`
712712
// 第一种方式
713713
n := [10]int{}
714714
n[1] = 10
715-
fmt.Println("-----1------",n) // 输出:`[0 10 0 0 0 0 0 0 0 0]`
715+
fmt.Println("-----1------",n) // 输出:`-----1------ [0 10 0 0 0 0 0 0 0 0]`
716716

717717
// 第二种方式
718718
m := new([10]int)
719719
m[1] = 20
720-
fmt.Println("-----2------",m) // 输出:`&[0 20 0 0 0 0 0 0 0 0]`
720+
fmt.Println("-----2------",m) // 输出:`-----2------ &[0 20 0 0 0 0 0 0 0 0]`
721721
```
722722

723723
###### 多维数组
@@ -804,7 +804,7 @@ func main() {
804804
s7 := []byte{'a','b','c','d','e','f','g','h','i','j','k'} // 切片底层对应的数组
805805

806806
slice_a := s7[2:5]
807-
fmt.Println(slice_a) // 输出的assica码 值 [99 100 101]
807+
fmt.Println(slice_a) // 输出的ascii码 值 [99 100 101]
808808
fmt.Println(string(slice_a)) // 格式化为字符串输出
809809
fmt.Println(len(slice_a),cap(slice_a))
810810

@@ -817,7 +817,7 @@ func main() {
817817
s8 = append(s8, 12, 48)
818818
fmt.Printf("%v %p", s8, s8) // 格式化打印值和内存地址:[0 0 0 12 48] 0xc042074030
819819

820-
// 追加的元素如果没有超多切片容量,则切片的地址是不变的,否则内存地址会变
820+
// 追加的元素如果没有超过切片容量,则切片的地址是不变的,否则内存地址会变
821821
s8 = append(s8, 66, 88)
822822
fmt.Printf("%v %p\n", s8, s8) // [0 0 0 12 48 66 88] 0xc042048060
823823

@@ -828,7 +828,7 @@ func main() {
828828
fmt.Println(s9) //[33 44 55 4 5 6 7]
829829

830830
copy(s10,s9)
831-
fmt.Println(s10) // [33 44 55]
831+
fmt.Println(s10) // [1 2 3]
832832

833833
copy(s9[2:4],s10[0:2])
834834
fmt.Println(s9) // [1 2 33 44 5 6 7]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /