GO语言小锤硬磕十三、数组与切片
创始人
2025-06-01 21:26:16
0

数组用来保存一组相同类型的数据,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博客

相关内容

热门资讯

独家丨人形机器人最大融资背后,... 人形机器人,迎来一针暴力强心剂。投中网获悉,银河通用已完成新一轮融资,规模超过3亿美元(约合超21亿...
行业发展引擎切换,房企竞逐“好... 本文来源:时代周报 作者:唐洛当下,房地产市场的关键词已经从“高速发展”转向“高质量发展”,“好房子...
越来越多的中国人,为什么要戴呼... 前不久,“黄磊戴呼吸机睡觉”话题冲上热搜。黄磊戴呼吸机睡觉 来源:《向往的生活》原来,黄磊长期受打鼾...
芯联集成赵奇:构筑三条增长曲线... 中经记者 孙汝祥 夏欣 北京报道“感恩科创成长层,为‘硬科技’企业铺平创新发展之路。”芯联集成(68...
两位总裁?百济神州宣布全球研发... 百济神州高管迎来变动。12月18日晚间,百济神州有限公司(百济神州,ONC.US;6160.HK;6...
近3年七成主动权益基金正收益,... 文/每日财报 楚风临近年末,公募基金年度业绩排名即将出炉。今年来,A股市场走强,上证指数一度突破4...
锚定高质量发展 践行金融为民初... 12月18日,中银三星人寿凭借在业务发展、战略践行、社会责任等多维度的卓越表现,荣膺“2025金柿奖...
沐曦上市,葛卫东日赚近200亿... 据节点财经获悉,投资大佬葛卫东布局GPU企业沐曦股份,日赚近200亿元,而他投资的另一家企业五一视界...
中国这座城市楼市反攻!机构:明... 2025 年本港楼市成功 “反攻”,住宅物业交投节节上升,楼价亦企稳回升,四年来首见 “量额价” 齐...