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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值