-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4bd951a
commit 0548868
Showing
1 changed file
with
92 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,122 @@ | ||
Go和其他语言一样,也有数组类型,数组是长度固定的数据类型,必须存储一段相同类型的元素。数组存储的类型可以是内置类型,比如整型或者字符串,也可以是自定义的数据结构。 | ||
|
||
|
||
|
||
### Go语言的数组 | ||
但是Go语言的数组又有特殊的地方: | ||
|
||
- 数组是值类型,赋值和传参会复制整个数组,⽽不是指针(在Go语言中,所有的赋值都是传值) | ||
- 数组⻓度必须是常量,并且数组长度是数组类型的组成部分,也就是说`[2]int`和`[3]int`是不同类型 | ||
- 数组⽀持 "=="、"!=" 操作符 | ||
- 指针数组 [n]*T,数组指针 *[n]T | ||
|
||
|
||
|
||
### 声明和初始化 | ||
|
||
var nums [6]int | ||
数组的声明需要表明: | ||
|
||
- 存储数据的类型 | ||
- 存储元素的数量,即数组长度 | ||
|
||
var nums [6]int | ||
nums = [6]int{1, 2, 3, 4, 5, 6} | ||
例如,下面代码声明了一个数组`array`,但是还没有对它进行初始化,这时候数组里面的值是对应元素类型的零值。 | ||
|
||
var nums [6]int | ||
|
||
|
||
nums := [6]int{1, 2, 3, 4, 5, 6} | ||
数组一旦声明后,其元素类型和大小都不能变了,如果还需要存储更多的元素,那么只能通过创建一个新的数组,然后把原来数组的数据复制过去。 | ||
|
||
刚刚声明的数组已经被默认的元素类型零值初始化了,如果再次进行初始化,可以采用如下办法: | ||
|
||
nums := [...]int{1, 2, 3, 4, 5, 6} | ||
var nums [6]int | ||
nums = [6]int{1, 2, 3, 4, 5, 6} | ||
|
||
Go为我们提供了`:=`操作符(不仅适用于数组,还适用于任何数据类型,**但是只能用在函数中**),可以在创建数组的时候直接初始化: | ||
|
||
array := [6]int{0, 1, 0, 4, 0, 0} | ||
array := [6]int{1: 1, 3: 4} | ||
nums := [6]int{1, 2, 3, 4, 5, 6} | ||
|
||
当然也可以连数组的长度都不指定,使用`...`代替,Go会自动推导出数组的长度: | ||
|
||
nums := [...]int{1, 2, 3, 4, 5, 6} | ||
|
||
假如只想给索引为1和3的数组初始化相应的值,其他都为0,直接的办法如下: | ||
|
||
array := [6]int{0, 1, 0, 4, 0, 0} | ||
|
||
还有一种简便的办法,前面讲到数组默认初始化为零值,那么就可以利用这个特性,只初始化索引1和3的值: | ||
|
||
array := [6]int{1: 1, 3: 4} | ||
|
||
|
||
|
||
### 数组遍历 | ||
|
||
func main() { | ||
array := [5]int{1: 1, 3: 4} | ||
for i := 0; i < 5; i++ { | ||
fmt.Printf("索引:%d,值:%d\n", i, array[i]) | ||
数组元素的访问直接通过操作符`[]`即可,同样数组的遍历也非常方便。 | ||
|
||
可以直接使用`len`得到数组的长度,然后通过`for`进行遍历: | ||
|
||
func main() { | ||
array := [5]int{1: 1, 3: 4} | ||
|
||
for i := 0; i < len(array); i++ { | ||
fmt.Printf("索引:%d,值:%d\n", i, array[i]) | ||
} | ||
} | ||
} | ||
|
||
在Go中,也可以直接使用`for range`对数组进行遍历: | ||
|
||
func main() { | ||
array := [5]int{1: 1, 3: 4} | ||
for i, v := range array { | ||
fmt.Printf("索引:%d,值:%d\n", i, v) | ||
func main() { | ||
array := [5]int{1: 1, 3: 4} | ||
for i, v := range array { | ||
fmt.Printf("索引:%d,值:%d\n", i, v) | ||
} | ||
} | ||
} | ||
|
||
|
||
### 数组作为函数参数 | ||
|
||
同样类型的数组是可以相互赋值的,不同类型的不行,会编译错误。那么什么是同样类型的数组呢?Go语言规定,必须是长度一样,并且每个元素的类型也一样的数组,才是同样类型的数组。 | ||
### 数组的赋值 | ||
|
||
前面提到,数组是值类型,赋值和传参会复制整个数组。下面就通过一个例子验证: | ||
|
||
array := [5]int{1: 1, 3: 4} | ||
var array1 [5]int = array //success | ||
var array2 [4]int = array1 //error | ||
func main() { | ||
arr1 := [3]int{1, 2, 3} | ||
arr2 := arr1 | ||
arr2[2] = 10 | ||
|
||
fmt.Println(arr1) | ||
fmt.Println(arr2) | ||
} | ||
|
||
代码的输出为: | ||
|
||
func main() { | ||
array := [5]int{1: 2, 3:4} | ||
modify(array) | ||
fmt.Println(array) | ||
} | ||
func modify(a [5]int){ | ||
a[1] =3 | ||
fmt.Println(a) | ||
} | ||
[1 2 3] | ||
[1 2 10] | ||
|
||
可以看到使用`arr1`对`arr2`赋值操作后,`arr2`是完整的数组复制,对`arr2`的改动不会对`arr1`产生任何影响。 | ||
|
||
func main() { | ||
array := [5]int{1: 2, 3:4} | ||
modify(&array) | ||
fmt.Println(array) | ||
} | ||
func modify(a *[5]int){ | ||
a[1] =3 | ||
fmt.Println(*a) | ||
} | ||
同时需要注意,同样类型的数组是可以相互赋值的,不同类型的不行,会编译错误。那么什么是同样类型的数组呢?Go语言规定,**必须是长度一样,并且每个元素的类型也一样的数组,才是同样类型的数组**。 | ||
|
||
|
||
|
||
### 数组作为函数参数 | ||
|
||
在函数间传递变量时,总是以值的方式,如果变量是个数组,那么就会整个复制,并传递给函数,如果数组非常大,比如长度100多万,那么这对内存是一个很大的开销。 | ||
|
||
由于大数组的值拷⻉⾏为会造成性能问题,通常会建议使⽤`slice`,或数组指针,例如: | ||
|
||
func main() { | ||
array := [5]int{1: 2, 3:4} | ||
|
||
modify(&array) | ||
fmt.Println(array) | ||
} | ||
|
||
func modify(a *[5]int){ | ||
a[1] =3 | ||
fmt.Println(*a) | ||
} | ||
|
||
上面的代码传递数组的指针,所以这种情况节省了复制的内存。 | ||
但是要谨慎使用,因为一不小心,就会修改原数组,导致不必要的问题。 | ||
|