数组和切片

数组

数组可以存放多个同一类型数据。数组也是一种数据类型,在Go中,数组是值类型。

//数组的定义
//var 数组名 [数组大小]数据类型
func main()  {
	var arr [6]float64
	arr[0]=4.2
	arr[1]=2.4
}

用%p取址
在这里插入图片描述
输入数组的值:

for i:=0;i<len(arr);i++ {
   fmt.Scanln(&arr[i])
   }

四种初始化数组的方式
方法一:

func main()  {
	var arr [3]int=[3]int{1,2,3}
	fmt.Println(arr)
	//输出:[1 2 3]
}

方法二:

func main()  {
	var arr =[3]int{1,2,3}
	fmt.Println(arr)
}

方法三:

func main()  {
	var arr =[...]int{1,2,3}
	fmt.Println(arr)
}

方法四:自己定义下标

func main()  {
	var arr =[...]int{1:800,0:200,2:10,4:5}
	fmt.Println(arr)
	//输出结果:[200 800 10 0 5]
}

也可以使用类型推导,arr : = [ … ] int { 1 : 5 ,0 : 3 } 这种。

数组的遍历

方式一:常规for循环遍历,或者直接用fmt.Println(arr)输出。
方式二:for-range结构遍历
这是go语言一种独有的结构,可以用来遍历访问数组的元素。
在这里插入图片描述
在这里插入图片描述

func main()  {
	var arr =[...]int{1:800,0:200,2:10,4:5}
	for index,val :=range arr{
		fmt.Printf("index=%v val=%v\n",index,val)
		//输出:
		//index=0 val=200
        //index=1 val=800
        //index=2 val=10
        //index=3 val=0
        //index=4 val=5
	}
}

也可以:

func main()  {
	var arr =[...]int{1:800,0:200,2:10,4:5}
	for index,_ :=range arr{
		fmt.Println(arr[index])
	}
}

数组使用注意事项
在这里插入图片描述
8.传数组名的话是值传递,这点与c++不同。go中要是需要改变实参,传的时候应该&arr,且函数形参那里应该是arr *[3]int,指针类型。

在这里插入图片描述
main函数中arr是长度为3的数组,而modify函数中arr是切片,二者是不同的,所以不能这样传递。长度是数据类型的一部分,长度不同也不能传递。
在这里插入图片描述

slice切片

1.切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制。
2.切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度len都一样。
3.切片的长度是可变的,因此切片是一个可以动态变化的数组。
4.切片定义的基本语法:var 变量名 [ ]数据类型

切片的定义

func main()  {
	var slice=[]int{1,2,5,8,10,4,7}
	fmt.Println(slice)
	//输出:[1 2 5 8 10 4 7]
}

也可以类型推导:

func main()  {
	var intArr=[6]int{1,2,5,8,10,4}
	slice:=intArr[1:3]
	//1:3表示将intArr位置下标为1,最后下标为3但不包含3的元素
	//也就是下标[1,3)
	fmt.Println(slice)
	fmt.Println("slice的容量=",cap(slice))
	//切片的容量是可变的
}

slice首地址是intArr中第二个元素的地址,因为它引用是从下标为1的元素开始的。slice存储了地址,长度,容量这些信息,类似于结构体。
在这里插入图片描述
在这里插入图片描述
所以,在slice里修改下标为1的元素,该元素在原来数组intArr中对应下标为2,那么在intArr数组中对应下标为2的元素也会改变。
例:

func main()  {
	var arr=[6]int{1,2,3,4,5,6}
	slice:=arr[1:4]
	fmt.Println(slice)
	slice[0]=9
	fmt.Println(slice)
	fmt.Println(arr)
	//输出:
	//[2 3 4]
    //[9 3 4]  
    //[1 9 3 4 5 6]
}

切片使用的三种方式
方式一:就是上面提到的引用intArr数组
在这里插入图片描述
方式二:var 切片名 [ ]type=make([ ]type,len,cap)
其中cap(容量)>len(长度)
在这里插入图片描述

func main()  {
	var slice []int=make([]int, 3)
	fmt.Println(slice)
	//输出:[0 0 0]
	//cap也可以不填
}

在这里插入图片描述
方式三:与定义数组相似,只是[ ]里没有…
var slice [ ]int=[ ] int { 1 , 2 , 3 }
也可以var slice=[ ] int { 1 , 2 , 3 }效果是一样的。

方式一与方式二的区别:
使用make时,slice的cap和len是相等的。
在这里插入图片描述
切片的遍历
在这里插入图片描述
在这里插入图片描述
切片注意事项:
在这里插入图片描述
切片可以继续切片:
因为切片是引用类型,所以slice2中元素一旦重新赋值,slice和原数组arr对应位置的元素都会改变,因为它们指向的数据空间是同一个数据空间。
在这里插入图片描述
用append直接给slice追加具体元素
slice=append(slice,400,400)

也可以给slice*2:slice=append(slice,slice)

在这里插入图片描述
利用copy内置函数拷贝:
将para2拷贝给para1
在这里插入图片描述
举例:

func main()  {
	var slice1 = []int{1,2,3}
	var slice2 = make([]int,10)
	copy(slice2,slice1)
	fmt.Println(slice2)
	//[1 2 3 0 0 0 0 0 0 0]
}

当slice2的容量小于slice1的长度时,也可以拷贝,不会报错。

var slice1=[]int{1,2,3}
var slice2=make([]int,2)
copy(slice2,slice1)
fmt.Println(slice2)
//[1 2],slice2的容量是2
//所以只能copy到slice1的前两个元素。

案例一:
在这里插入图片描述
案例二:
在这里插入图片描述
string和slice
string底层是一个byte数组,因此string也可以进行切片处理。

func main()  {
	var str string="hello@nihao"
	slice:=str[6:]
	fmt.Println(slice)
	//nihao
}

在这里插入图片描述
string是不可变的,所以不能以str[5]='p’这种方式修改字符串。
如果需要修改字符串,可以先将string->[ ]byte/[ ]rune->修改->重写转成string。
例:

func main()  {
	var str string="hello@nihao"
	arr:=[]byte(str)
	arr[0]='z'
	str=string(arr)
	fmt.Println(str)
	//zello@nihao
	//细节:我们转成[]byte后,可以处理英文和数字
	//但不能处理汉字
	//原因是[]byte 字节来处理,而一个汉字三个字节
	//因此会出现乱码
}

解决方法:将string转成[ ]rune,因为[ ]rune是按字符处理,兼容汉字。

func main()  {
	var str string="hello@nihao"
	arr:=[]rune(str)
	arr[0]='呗'
	str=string(arr)
	fmt.Println(str)
	//呗ello@nihao
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值