go语言数组切片

go数组操作灵活多变,借此机会复习一下这部分内容吧!

数组:长度固定,不能修改长度,长度通过内置函数len(array)获取。数组是值类型。

切片:动态数组,长度不固定

切片有两个概念:len为长度,cap为容量。

长度是指已经被赋过值的值的数量(最大下标+1),可通过内置函数len()获得。

容量是指切片目前可容纳的最多元素个数,通过内置函数cap()获得。切片是引用类型,传递切片时将引用同一指针,修改值将会影响其他的对象。 

切片可理解为动态数组,是特殊的数组

数组的声明

//第一种
//var <数组名称> [<数组长度>]<数组元素>
var arr [2]int
arr[0]=1
arr[1]=2

//第二种
//var <数组名称> = [<数组长度>]<数组元素>{元素1,元素2,...}
var arr2 = [2]int{1,2}
//或者
arr3 := [2]int{1,2}

//第三种,...表示长度不固定,此时为不定长数组,未初始化的索引值将默认置为0
//var <数组名称> [<数组长度>]<数组元素> = [...]<元素类型>{元素1,元素2,...}
var arr4 = [...]int{1,2}
//或者
arr5 := [...]int{1,2}

//第四种
//var <数组名称> [<数组长度>]<数组元素> = [...]<元素类型>{索引1:元素1,索引2:元素2,...}
var arr6 = [...]int{2:5,1:1}
//或者
arr7 := [...]int{2:5,1:1}
//未提供初始值的元素自动初始化为0,第三个元素值是5  值为:[0 1 5]  

指针数组

var x,y int = 2,1
a:=[]*int{&x,&y}	//该数组的元素为指针,即指针数组
p:=&a	
fmt.Printf("%T ; ",p)	//*[]*int
fmt.Printf("%T ; ",a)	//[]*int

修改数组中的某元素

// 根据索引可直接修改
demo:=[2]int{1,2}
demo[1]=1
fmt.Println("修改数组某元素后:",demo)		//[1 1]

//使用数组的指针操作该数组
b:=[5]int{2,3,4}
q:=&b
q[4]=99
//b[2:]意思是取b数组中索引>=2的值,
fmt.Println(q,b[2:])	//q=&[2 3 4 0 99] b[2:]=[4 0 99]

索引取值

c:=[...]int{9,8,7,6,5,4,3,2,1,0}
/* 打印子切片从索引1(包含) 到索引3(不包含),前闭后开*/
fmt.Println("c[:]=",c[:],",c[:1]=",c[:1],",c[1:3]=",c[1:3])
//c[:]= [9 8 7 6 5 4 3 2 1 0] ,c[:1]= [9] ,c[1:3]= [8 7]
fmt.Println("c[:]值=",c[:],"len(c[:])=",len(c[:]),",cap(c[:])=",cap(c[:]))
//c[:]值= [9 8 7 6 5 4 3 2 1 0] len(c[:])= 10 ,cap(c[:])= 10
fmt.Println("c[2:5]值=",c[2:5],"len(c[2:5])=",len(c[2:5]),",cap(c[2:5])=",cap(c[2:5]))
//c[2:5]值= [7 6 5] len(c[2:5])= 3 ,cap(c[2:5])= 8
fmt.Println("c[2:5:7]值=",c[2:5:7],"len(c[2:5:6])=",len(c[2:5:6]),",cap(c[2:5:6])=",cap(c[2:5:6]))
//c[2:5:7]值= [7 6 5] len(c[2:5:6])= 3 ,cap(c[2:5:6])= 4
//len=high-low,cap=max-low,c[2:5:6]即c[low:high:max],

数组作为函数参数

//函数传入的形参类型与待传入的数组类型一致(如都是动态或定长数组)时直接写数组名即可,否则写arr[:]
func main() {
	fmt.Println("-------1-传入一个定长数组:需要arr[:]-----")
	var arr =[5]int{3,4,5}
	x:=makeslice(arr[:])
	fmt.Println(x)	//[111 4 5 0 0 112]
	fmt.Println("-------2-传入一个动态数组(切片):直接arr-----")
	var arr2 =[]int{33,43,53}
	ab:=makeslice(arr2)
	fmt.Println(ab)		//[111 43 53 112]
	fmt.Println("-------3-传入一个定长数组-----")
	var arr3 =[3]int{33,43,53}
	abc:=makeslice2(arr3)
	fmt.Println(abc)	//[111 43 53]
	fmt.Println("-------4-传入一个动态数组:错误,函数makeslice2只能传入定长数组-----")
	var arr4 =[]int{33,43,53}
	abd:=makeslice2(arr4)	//报错 Cannot use 'arr4' (type []int) as type [3]int 
	fmt.Println(abd)
}

//该函数传入一个动态数组,即调用时makeslice(arr)需要传入的是不限制大小的数组
func makeslice(arr []int) []int{
	arr[0]=111
	arr = append(arr,112)
	return arr
}

//该函数传入一个定长数组,固定长度为3,即传入的类型必须是(type [3]int)
func makeslice2(ar [3]int) [3]int{
	ar[0]=111
	return ar
}

特别实践

//传参时arr和arr[:]的区别
func main() {
	//不能修改成功
	var arr = [3]int{3, 4, 5}
	update1(arr)
	fmt.Println(arr) // [3 4 5]

	//能修改成功
	var arr2 = [3]int{3, 4, 5}
	update2(arr2[:])
	fmt.Println(arr2) // [111 4 5]
}

func update1(arr [3]int) {
	arr[0] = 111
}

//参数为切片时需要传arr2[:]而不是arr2
func update2(arr []int) {
	arr[0] = 111
}

切片创建与赋值

//创建容量为5的切片
x:= make([]int ,3,5)
fmt.Println("原始数组x:",x)		//[0 0 0]
//追加数据,当超出容量限制时,自动分配更大的存储空间
for i := 1; i < 8; i++ {
	//给切片x继续添加元素,从x的第四个元素开始存起
	x = append(x,i)
}
fmt.Println(x)	//[0 0 0 1 2 3 4 5 6 7]
x[1] = 99
fmt.Println(x)	//[0 99 0 1 2 3 4 5 6 7]

不断学习、不断实践、不断总结、不断进步!

发布了155 篇原创文章 · 获赞 74 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/HYZX_9987/article/details/102960511