golang 数组_切片

本文详细介绍了Go语言中的数组与切片的概念、使用方法和注意事项,包括数组的定义、遍历、初始化,切片的创建、遍历、动态增长以及增删改查操作。还涉及到值传递与指针、二维数组以及切片与数组底层的关系。通过实例展示了切片如何引用数组部分以及如何通过make创建切片。最后,通过代码演示了切片的常用操作,如append、copy等。
摘要由CSDN通过智能技术生成


数组

  • 定义: var arr [5]int
  • 上面的数组类型为:[5]int; 数组长度属于数组类型的一部分;
  • 二维数组: var arr2d [2][3]int //arr2d类型是:[2][3]int

数组遍历

  • 普通for 循环 + len()
  • for-range 循环

数组初始化

  • var arr1 [3]int = [3]int{1,2,3};
  • var arr2 = [3]int{1,2,3};
  • var arr3 = [...]int{1,2,3,67,8};
  • var arr4 = [...]int{2:22,3:33, 1:11}; // 指定索引位置
  • var arr2d [2][3]int = [2][3]int{{1, 2, 3}, {4, 5, 6}}

数组注意事项

  • 数组属于值类型;在默认情况下是值传递,会进行值拷贝;
  • 因此如果想在其他的函数种修改原来的数组,需要使用指针的方式;

切片

  • 数组长度不可变,有些不够灵活;
  • 切片构建在数组之上并且提供更强大的能力和便捷性;
  • 切片是对数组一个连续片段的引用,切片是一个引用类型;
  • 定义:slice := intarr[1:3]
  • 切片元素个数:len(slice)
  • 切片容量:cap(slice), 容量可以动态变化
  • 切片的数据结构包含3个字段:指向底层数组的指针;切片的长度;切片的容量;

切片的几种定义方式

  • 定义一个切片,让切片去引用一个已经创建好的数组的部分/整体;
  • 定义一个切片,直接指向具体数组: var sliceName []int = []int{1, 2, 3}
  • 通过 make 内置函数来创建切片: var sliceName []int = make([]int, len, [cap])

切片遍历

  • for+len
  • for-range

切片注意事项

  • 切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用;
  • 切片使用不能越界;
  • 切片可以继续切片;
  • 切片底层的数组不能直接维护/操作,需要通过切片间接维护/操作;
  • 一些写法:简写
    • var slice = arr[0:end] -> var slice = arr[:end]
    • var slice = arr[start:len(arr)] -> var slice = arr[start:]
    • var slice = arr[0:len(arr)] -> var slice = arr[:]
  • 切片可以动态增长;
  • 添加元素:sliceReturn := append(sliceOld, 1, 2) / slice1 := append(slice1, slice2...)
    • append 会创建一个新数组,将sliceOld的元素复制到新数组种,并在新数组中追加新的要添加的元素;
    • append 后需要使用返回后的值;返回值指向新的数组;
    • 要修改原来的切片,则 sliceOld = append(sliceOld, 1, 2)

切片增删改查

  • 增加:append
  • 拷贝:copy
  • 查询:sliceName[index]

代码

package main

import "fmt"

func main() {
	var arr [5]int
	for i := 0; i < len(arr); i++ {
		arr[i] = i
	}

	// 数组遍历
	fmt.Println("for-len:")
	for i := 0; i < len(arr); i++ {
		fmt.Printf("arr[%d]= %d ;", i, arr[i])
	}

	fmt.Println()
	fmt.Println("for-range:")
	for idx, val := range arr {
		fmt.Printf("idx=%d, val=%d; ", idx, val)
	}
	// 初始化
	fmt.Println("\n初始化:")
	var arr1 [3]int = [3]int{1,2,3}
	var arr2 = [3]int{1,2,3}
	var arr3 = [...]int{1,2,3,67,8}
	var arr4 = [...]int{2:22,3:33, 1:11}
	fmt.Println(arr1, arr2, arr3, arr4)
	fmt.Printf("arr4 类型为:%T \n", arr4)
	fmt.Printf("arr4 类型为:#{arr4} \n")
	fmt.Println("数组值传递测试:")
	fmt.Println("修改前:", arr4)
	valTest(arr4)
	fmt.Println("修改后:", arr4)
	valTestxP(&arr4)
	fmt.Println("指针方式修改后:", arr4)
	fmt.Println("二维数组定义测试:")
	var arr2d [2][3]int
	fmt.Println(arr2d)
	fmt.Printf("arr2d类型是:%T \n", arr2d)
	fmt.Printf("arr2d 的地址:%p \n", &arr2d)
	fmt.Printf("arr2d[0] 的地址:%p \n", &arr2d[0])
	fmt.Printf("arr2d[0][0] 的地址:%p \n", &arr2d[0][0])
	arr2d = [2][3]int{{1, 2, 3}, {4, 5, 6}}
	fmt.Println(arr2d)

	fmt.Println("==>> 切片定义实例:")
	var intArr [6]int = [6]int {1, 2, 3, 4, 5, 6}
	var slice [] int = intArr[1:3]
	fmt.Println(slice)
	fmt.Println("切片元素个数:", len(slice))
	fmt.Println("切片容量:", cap(slice))
	fmt.Printf("intArr[1] 的地址: %p \n", &intArr[1])
	fmt.Printf("slice[0] 的地址: %p \n", &slice[0])

	sliceMake := make([]int, 4, 20)
	fmt.Println("sliceMake: ", sliceMake)
	fmt.Println("sliceMake.len:", len(sliceMake))
	fmt.Println("sliceMake.cap:", cap(sliceMake))
	sliceMake[3] = 33
	fmt.Println("sliceMake:", sliceMake)

	slice2 := []int{1, 2, 3}
	fmt.Println("slice2:", slice2)
	fmt.Println("slice2.len:", len(slice2))
	fmt.Println("slice2.cap:", cap(slice2))

	fmt.Println("==>> 切片遍历(slice2),for+len:")
	for i := 0; i < len(slice2); i++ {
		fmt.Printf("slice2[%v] = %v\n", i, slice2[i])
	}
	fmt.Println("==>> 切片遍历(slice2),for-range:")
	for ind,val := range slice2 {
		fmt.Printf("slice2[%v] = %v\n", ind, val)
	}
	fmt.Println("==>> 切片追加元素:")
	slice3 :=append(slice2, 33)
	fmt.Println("slice2:", slice2)
	fmt.Println("slice3:", slice3)
	fmt.Println("==>> 切片追加元素, 并将返回值赋值给自身:")
	slice2 =append(slice2, 33)
	fmt.Println("slice2:", slice2)

	fmt.Println("==>> 切片追加给切片(slice2+slice2):")
	slice2 = append(slice2, slice2...)
	fmt.Println("slice2:", slice2)

	fmt.Println("==>> 切片拷贝:")
	sliceFrom := []int{1, 2, 3}
	sliceTo := make([]int, 10)
	fmt.Println("sliceFrom:", sliceFrom)
	fmt.Println("sliceTo, 拷贝前:", sliceTo)
	copy(sliceTo, sliceFrom)
	fmt.Println("sliceTo,拷贝后:", sliceTo)
}

func valTest(arr [4]int){
	arr[1] = 44
}

func valTestxP(arr *[4]int){
	(*arr)[1] = 44
	// go 默认解地址
	arr[2] = 55
}

运行结果

for-len:
arr[0]= 0 ;arr[1]= 1 ;arr[2]= 2 ;arr[3]= 3 ;arr[4]= 4 ;
for-range:
idx=0, val=0; idx=1, val=1; idx=2, val=2; idx=3, val=3; idx=4, val=4; 
初始化:
[1 2 3] [1 2 3] [1 2 3 67 8] [0 11 22 33]
arr4 类型为:[4]int 
arr4 类型为:#{arr4} 
数组值传递测试:
修改前: [0 11 22 33]
修改后: [0 11 22 33]
指针方式修改后: [0 44 55 33]
二维数组定义测试:
[[0 0 0] [0 0 0]]
arr2d类型是:[2][3]int 
arr2d 的地址:0xc00000e570 
arr2d[0] 的地址:0xc00000e570 
arr2d[0][0] 的地址:0xc00000e570 
[[1 2 3] [4 5 6]]
==>> 切片定义实例:
[2 3]
切片元素个数: 2
切片容量: 5
intArr[1] 的地址: 0xc00000e638 
slice[0] 的地址: 0xc00000e638 
sliceMake:  [0 0 0 0]
sliceMake.len: 4
sliceMake.cap: 20
sliceMake: [0 0 0 33]
slice2: [1 2 3]
slice2.len: 3
slice2.cap: 3
==>> 切片遍历(slice2),for+len:
slice2[0] = 1
slice2[1] = 2
slice2[2] = 3
==>> 切片遍历(slice2),for-range:
slice2[0] = 1
slice2[1] = 2
slice2[2] = 3
==>> 切片追加元素:
slice2: [1 2 3]
slice3: [1 2 3 33]
==>> 切片追加元素, 并将返回值赋值给自身:
slice2: [1 2 3 33]
==>> 切片追加给切片(slice2+slice2):
slice2: [1 2 3 33 1 2 3 33]
==>> 切片拷贝:
sliceFrom: [1 2 3]
sliceTo, 拷贝前: [0 0 0 0 0 0 0 0 0 0]
sliceTo,拷贝后: [1 2 3 0 0 0 0 0 0 0]

Process finished with the exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值