golang 数组和切片

数组

数组的声明

数组的长度是固定的,声明的时候就需要确定,长度也是数组类型的一部分,所以两个长度不同的int数组也算是两个不同的类型。
声明方法:

var nums [5]int
var nums = [5]int{}
var nums = [5]int{1, 2, 3} //前三个元素初始化,剩下的元素为0
nums := [...]int{1, 2, 3} //也可以让程序计数,但是[]内不能空着,空着就会声明成切片slice
nums := [5]int{3:5} //将nums[3]初始化为5

数组的拷贝

数组是一种值类型而不是引用类型,所以将一个数组赋值给另一个数组时进行了值拷贝,两个数组独立互不影响

func main() {
	arr1 := [...]int{1, 2, 3}
	arr2 := arr1

	arr1[0] = 2

	fmt.Println(arr1) // [2 2 3]
	fmt.Println(arr2) // [1 2 3]
}

数组作为函数参数

因为数组是值类型,所以传参也会出现值拷贝,在函数中的操作对原数组不影响,如果想要修改原数组,需要&引用传递

func test1(arr [5]int) {
	arr[0] = 5
}

func test2(arr *[5]int) {
	arr[0] = 5
}

func main() {
	arr1 := [5]int{}
	test1(arr1)
	fmt.Println(arr1) // [0 0 0 0 0]
	test2(&arr1)
	fmt.Println(arr1) // [5 0 0 0 0]
}

切片

切片slice是对数组一个连续片段的引用,和数组不同,切片是引用类型,在内存中是一个有3个域的结构体,ptr是指向底层数组的指针,len是切片的长度,cap是切片的容量。

切片的声明

var arr = [5]int{1, 2, 3, 4, 5}
slice1 := arr[0:5] //对已存在的数组进行引用
slice2 := []int{1, 2, 3, 4, 5} //直接创建一个切片
slice3 := make([]int, 5, 10) //用make()创建并初始化一个切片,5是len长度,10是cap容量,cap参数可忽略

slice4 := new([]int) //返回指向slice4的指针,创建并给切片分配了内存,但是ptr为nil指针,没有初始化,len和cap都为0
slice5 := make([]int, 0) //创建并给切片分配了内存,并将ptr初始化指向一个空数组,len和cap都为0

切片的赋值和拷贝

切片是一种引用类型而不是值类型,一个切片赋值给另一个切片时,复制了一份指向同一位置的ptr,所以会互相影响

func main() {
	arr1 := []int{0, 0, 0}
	arr2 := arr1

	arr1[0] = 2

	fmt.Println(arr1) // [2 0 0]
	fmt.Println(arr2) // [2 0 0]
}

使用copy()对切片进行拷贝,将源切片的数据拷贝到目的切片中,是两份指向不同的切片,但不会帮目的切片分配空间

func main() {
	arr1 := []int{0, 0, 0}
	arr2 := make([]int, 3)
	copy(arr2, arr1)

	arr1[0] = 2

	fmt.Println(arr1) // [2 0 0]
	fmt.Println(arr2) // [0 0 0]
}

切片作为函数参数

切片本身就是引用类型,直接作为参数就可以对原数组进行修改,不要再用指针指向切片,如test2()

func test1(arr []int) {
	arr[0] = 5
}
//不要这样写:
func test2(arr *[]int) {
	(*arr)[0] = 6
}

func main() {
	arr1 := []int{0, 0, 0, 0, 0}
	test1(arr1)
	fmt.Println(arr1) // [5 0 0 0 0]
	test2(&arr1)
	fmt.Println(arr1) // [6 0 0 0 0]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang数组切片是两种不同的数据类型,用于存储相同数据类型的容器。数组的长度是固定的,而切片的长度是可变的。在日常应用中,切片的使用更为普遍。 数组在声明时需要指定长度,并且在初始化时必须提供相同长度的元素。例如,`a := int{1, 2, 3}`就是一个长度为3的整数数组数组的长度一旦确定后就不能更改。 切片是基于数组的引用类型。它不需要指定固定的长度,并且可以根据需要动态扩展或缩小。切片包装着底层数组,通过指定起始索引和结束索引来指定子集。例如,`b := a[:]`就是一个切片,它包含了数组a的所有元素。 数组适用于需要固定长度的场景,而切片适用于长度可变的情况。在实际应用中,切片更常用,因为它提供了更大的灵活性和便利性。 总结: - 数组是长度固定的容器,切片是长度可变的容器; - 数组在声明时需要指定长度,切片则不需要; - 数组的长度一旦确定后就不能更改,而切片可以根据需要动态扩展或缩小; - 切片是基于数组的引用类型,可以通过指定起始索引和结束索引来指定子集。 参考资料: Golang中的「数组」和「切片」都是存储同一数据类型的容器,只不过Golang中的数组长度是固定的,而切片的长度是可变化的。 切片是引用类型,切片包装的数组称为该切片的底层数组。我们来看一段代码://a是一个数组,注意数组是一个固定长度的,初始化时候必须要指定长度,不指定长度的话就是切片了 a := int{1, 2, 3} //b是数组,是a...。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值