数组用来保存一组相同类型的数据,go语言数组也分一维数组和多维数组。
直接上代码看一下一维数组特性
package main
import "fmt"
func main(){
//1.定义数组 var 数组名称 [元素个数]数据类型var arr1 [2]int //[0 0]定义就有为0的默认值var arr2 [3]bool //[false false false]//2.多种初始化方式//定义时完全初始化var arr3 [3]int = [3]int{1,3,5} //[1 3 5]//定义时部分初始化 var arr4 [3]int = [3]int{8,9} //[8 9 0] //定义时指定元素初始化var arr5 [3]int = [3]int{0:8,2:9} //[8 0 9]//先定义再逐个初始化,访问数组通过 数组名称[索引] 的方式var arr6 [3]stringarr6[0] = "ok"arr6[1] = "hello"arr6[2] = "world"//先定义再一次性初始化(与C语言数组不同)arr1 = [2]{1,2} //[1 2]arr2 = [3]{true,true,false} //[true true true]//3.定义元素同时初始化,元素的个数可以省略,使用 ... 代替var arr7 = [...]int{1,3,5} //[1 3 5]var arr8 = [...]int{6:5} //[0 0 0 0 0 0 5]//4.两种遍历数组的方式,for循环遍历,for...range循环遍历arr := [...]int{1,3,5}for i:=0; i
数组的注意点
go语言中数组长度是数据类型的一部分,长度不同类型不同,不能比较。
go语言数组类型相同,在比较时会按照“对应索引的元素”进行比较,所有元素都相同返回true,否则返回false
go语言的数组是值类型,赋值和传参会复制整个数组
package main
import "fmt"
func main(){var arr1 [2]intvar arr2 [3]intvar arr3 [3]intvar arr4 [3]intfmt.Println(arr2 == arr3) // true
// go语言中数组长度是数据类型的一部分,长度不同类型不同,不能比较。//fmt.Println(arr1 == arr2) 编译报错 //go语言数组类型相同,在比较时会按照“对应索引的元素”进行比较,所有元素都相同返回true,否则返回falsearr2 = [3]int{1,2,3}arr3 = [3]int{1,2,3}arr4 = [3]int{3,2,1}fmt.Println(arr2 == arr3) // truefmt.Println(arr2 == arr4) // false//go语言的数组是值类型,赋值和传参会复制整个数组arr4 = arr2arr2[0]=3fmt.Println(arr2) //[3 2 3] fmt.Println(arr4) //[1 2 3]}
二维数组
package main
import "fmt"
func main(){//创建一个两行三列数组arr := [2][3]int{{1,2,3},{4,5,6}, //注意:数组换行需要逗号结尾}fmt.Println(arr) //[[1 2 3][4 5 6]]//创建多维数组只允许第一维使用 ... arr1 := [...][3]int{{1,2,3},{4,5,6}}fmt.Println(arr1)
}
切片可以简单理解为长度可以变化的数组,但是go语言的切片本质上是结构体,用来解决数组在应用中长度不可变的问题
切片源码
type slice struct{
array unsafe.Pointer //指向底层数组指针
len int //切片长度(已经保存了多少个元素)
cap int //切片容量(可以保存多少个元素)
}
切片的创建方式
package main
import "fmt"
func main(){
//1.通过数组创建切片----------------------(切片的底层会指向数组,修改切片会修改对应位数组的值)var arr = [5]int{1,3,5,7,9}var sce = arr[1:3] //从下标1开始,一直取到3下标的前一个索引(左闭右开)fmt.Println(sce) //[3 5] fmt.Println(len(sce)) //切片的长度2 = 3 - 1 结束位置减开始位置fmt.Println(cap(sce)) //切片的容量4 = 5 - 1 数组长度减开始位置fmt.Printf("%p\n",&arr) fmt.Printf("%p\n",&arr[0]) //数组地址 是 数组首元素地址 fmt.Printf("%p\n",&arr[1]) fmt.Printf("%p\n",sce) //切片地址 是数组中指定的 开始元素的地址 (&arr[1])//指定骑士位置的四种方式var sce1 = arr[1:2] //指定开始和结束var sce2 = arr[:2] //只指定结束var sce3 = arr[2:] //只指定开始var sce4 = arr[:] //都不指定 //2.通过make函数创建q切片 make(类型,长度,容量) //内部会先创建一个数组,然后让切片指向数组//如果没有指定容量,那么容量和长度一样var sce5 = make([]int,3,5)fmt.Println(sce5) //[0 0 0]fmt.Println(len(sce5)) //3fmt.Println(cap(sce5)) //5/*实现var arr [5]int var sce = arr[0:3]*///3.通过go提供的语法糖快速创建//和创建数组相同,但是不能指定长度//创建时,切片的容量和长度相等var sce6 = []int{1,3,5}fmt.Println(sce6) fmt.Println(len(sce6)) //3fmt.Println(cap(sce6)) //3}
切片的使用
package main
import "fmt"
func main(){var sce = []int{1,3,5}
//1.同数组一样,使用 切片名称[索引] 的方式操作切片sce[1] = 666//2.不能越界sce[5] = 1 //编译报错//3.使用append方法对切片扩容----------------------------(返回新切片不会修改源底层指向数组)//append(切片,元素)会在切片末尾添加一个元素,返回追加数据之后的切片//追加后没有查出切片容量,返回原切片,超出容量返回新切片//append 每次扩容会按照(原有切片容量*2)的方式扩容fmt.Println(sce) //[1,666,5] fmt.Println(len(sce)) //3fmt.Println(cap(sce)) //3fmt.Printf("%p\n",sce) //一个地址 sce = append(sce , 666)fmt.Println(sce) //[1,666,5,666] fmt.Println(len(sce)) //3fmt.Println(cap(sce)) //6fmt.Printf("%p\n",sce) //一个新地址 //4.使用copy用于两个切片之间数据拷贝 copy(目标切片,切片源)var sce1 = []int{1,2,3}var sce2 = make([]int,5)var sce3 = make([]int,2)//复制sce1的切片数据到sce2,这时他们的内存指向地址不同copy(sce2,sce1) //sce2 [1,2,3,0,0]//拷贝数据以小容量为准copy(sce3,sce1) //sce3 [1,2]//切片是引用传递 底层会指向同一个数组,再次修改sce2,sce1也会变sce2 = sce1
}
切片的注意点
package main
import "fmt"
func main(){
//1.可以通过切片中再次生成新的切片,两个切片底层指向同一数组,修改一个会影响另一个arr := [5]int{1,3,5,7,9}sce1 := arr[0:4]sce2 := sce1[0:3]fmt.Println(sce1) //[1 3 5 7]fmt.Println(sce2) //[1 3 5]sce2[1] = 666fmt.Println(sce1) //[1 666 5 7] fmt.Println(sce2) //[1 666 5]fmt.Println(arr) //[1,666,5,7,9] 会修改指向的数组//2.切片只支持判断是否为nil,不支持==、!= 判断//fmt.Println(sce1 == sce2)//编译报错fmt.Println(sce1 != nil)//truefmt.Println(sce2 == nil)//false//3.只生命当没有被创建的切片是不能使用的var arr [3]int //数组声明后直接可使用var sce []int //切片生命后不能直接使用 只有通过make或者放糖创建后才会开辟空间使用var sce[0] = 2 //编译报错//4.字符串的底层是[]byte数组,所以字符也支持切片操作str := "abcdefg"sce1 := str[3:]fmt.Println(sce1)sce2 := make([]byte,10)//第二个参数只能是slice或者数组//将字符串拷贝到切片中copy(sce2,str)fmt.Println(sce2) //[97 98 99 100 101 102 103 0 0 0]}
下一篇转载 go切片与数组的关系—修改切片导致数组被修改的问题_shockWaveGo的博客-CSDN博客