数组
简介
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。数组形式 numbers[0], numbers[1] ..., numbers[99] 更加方便且易于扩展。数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。数组不可以动态增长和收缩元素个数。数组的元素可以被修改,但是数组本身的赋值和函数传参都是以整体复制的方式处理的。
声明
var variable_name [SIZE] variable_type
初始化
package main import "fmt" func main() { // 第一种方式 []中的数值与{}中的个数要保持一致 var list1 = [4] int{1, 2, 3, 4} fmt.Println(list1) // 第二种方式 根据{}中元素个数设置数组大小 var list2 = [...] string{"a","b","c","d"} fmt.Println(list2) // 第三种方式 []中的数值与{}中的个数要保持一致 list3 := [4] float32{1.1,2.2,3.3,4.4} fmt.Println(list3) } //[1 2 3 4] //[a b c d] //[1.1 2.2 3.3 4.4]
元素的值
package main import "fmt" func main() { list := [4] int{1,2,3,4} fmt.Println(list) // 数组交换 修改元素 list[0],list[1] = list[1],list[0] fmt.Println(list) } //[1 2 3 4] //[2 1 3 4]
遍历
package main import "fmt" func main() { list := [4]string {"a","b","c","d"} // 获取下标与值 for i,v := range list{ fmt.Println(i) fmt.Println(v) } // 忽略迭代时的下标 var times [5][0]int for range times { fmt.Println("hello") } } //0 //a //1 //b //2 //c //3 //d //hello //hello //hello //hello //hello
空数组
var d [0]int // 定义一个长度为0的数组 var e = [0]int{} // 定义一个长度为0的数组 var f = [...]int{} // 定义一个长度为0的数组
赋值
Go语言中数组是值语义。一个数组变量即表示整个数组,它并不是隐式的指向第一个元素的指针(比如C语言的数组),而是一个完整的值。当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。如果数组较大的话,数组的赋值也会有较大的开销
package main import "fmt" func main() { list1 := [4] int{1,2,3,4} list2 := list1 // 赋值 拷贝整个数组的内存 fmt.Printf("list1 %p ",&list1) fmt.Printf("list2 %p ",&list2) } //list1 0xc000054140 //list2 0xc000054160
赋值生成的数组与原数组互不影响
package main import "fmt" func main() { list1 := [4] int{1,2,3,4} list2 := list1 // 赋值的数组之间互不影响 list1[0] = 10 fmt.Printf("list1 %d ",list1) fmt.Printf("list2 %d ",list2) } //list1 [10 2 3 4] //list2 [1 2 3 4]
内置函数len
可以用于计算数组的长度,cap
函数可以用于计算数组的容量。不过对于数组类型来说,len
和cap
函数返回的结果始终是一样的,都是对应数组类型的长度。
package main import "fmt" func main() { list := [4]string {"a","b","c","d"} // len cap fmt.Printf("len=%d cap=%d slice=%v ",len(list),cap(list),list) } //len=4 cap=4 slice=[a b c d]
函数传参
数组作为参数进行函数传递时,数组会进行内存拷贝(与赋值一样),在函数中对参数数组进行修改操作时,不会对外部数组有任何影响
package main import "fmt" // 传参时指定数组的size func change(list [4]int){ // 数组作为参数时会拷贝内存 fmt.Printf("list %p ",&list) // 对数组进行修改 list[0] = 100 } func main() { list := [4] int{1,2,3,4} fmt.Printf("list %p ",&list) change(list) // list 不受影响 fmt.Println(list) } //list 0xc000054140 //list 0xc000054180 //[1 2 3 4]
数组地址与元素地址
数组在内存中时连续的,并且数组变量的地址与数组第一个元素地址一致
package main import "fmt" func main() { list := [4] int{1,2,3,4} // 内存地址一致 fmt.Printf("list %p ",&list) fmt.Printf("list %p ",&list[0]) } //list 0xc00000e380 //list 0xc00000e380
数组进行切片,生成的切片与数组
生成的切片与数组同下标元素的内存地址一致,修改值后相互影响
package main import "fmt" func main() { list := [] int{1,2,3,4} slice := list[:] // 同下标的切片元素的数组元素地址一致 fmt.Printf("list[0] %p ",&list[0]) fmt.Printf("list[0] %p ",&slice[0]) // 修改元素的值相互影响 slice[0] = 10 fmt.Println(list) fmt.Println(slice) list[0] = 20 fmt.Println(list) fmt.Println(slice) } //list[0] 0xc000054140 //list[0] 0xc000054140 //[10 2 3 4] //[10 2 3 4] //[20 2 3 4] //[20 2 3 4]