Go语言中数组和切片的用法
程序员文章站
2024-01-29 22:50:28
...
主要讲解Go语言中数组、切片(Slice) 的使用
主要知识点:
- 熟悉定义数组的几种方式
- 二维数组的用法
- 数组是值类型(默认情况下 Go中所有的参数传递都是值传递)
- [3]int 、[5]int 长度不一样,被认为是不同的数据类型
- Go语言中 一般不直接使用数组,也不直接使用带指针的数组,而是使用切片(Slice)
- 切片是对数组的一个视图,虽然Slice本身是值类型,但是它内部使用了对数组的指针引用,所以修改切片数据,会将数组原有数据修改掉
- Slice可以向后扩展,不能向前扩展,扩展规则为:s[i] 不可以超越len(s),向后扩展不可以超过cap(s)
- 向 Slice 添加元素
以下通过代码进行示例:
package main
import "fmt"
//数组的几种定义方式,数量要写在类型的前面
func array(){
var arr1 [5]int //普通定义方法,不定义初始值
arr2:=[3]int{1,2,3} //定义数组时设置初始值
arr3:=[...]int{2,4,6,8,10}//不指定长度,运行时让系统自己计算
var grid [4][5]int //定义二维数组
fmt.Println(arr1,arr2,arr3)//[0 0 0 0 0] [1 2 3] [2 4 6 8 10]
fmt.Println(grid) //[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
//遍历数组的方式 1 :普通用法
for i:=0;i<len(arr2);i++{
fmt.Println(arr2[i]) //分别输出 1,2,3
}
//遍历数组的方式 1 :推荐用法用法(使用 range 关键字)
for i,v:=range arr2 {
fmt.Println(i,v)
//0 1
//1 2
//2 3
}
}
//[]int 参数中没有指定数组长度,此时代表为 Slice
func updateSlice(s []int) {
s[0] = 100
}
func slice() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
//获取数组的中括号中使用区间,被称为切片 (Slice)
//以下为切片的基础使用方式
//获取下标 2-6 之间的数值
fmt.Println("arr[2:6] =", arr[2:6]) //[2 3 4 5]
//获取下标从开始到第6位的值
fmt.Println("arr[:6] =", arr[:6]) //[0 1 2 3 4 5]
//获取下标从2到最后的值
fmt.Println("arr[2:] =", arr[2:]) //[2 3 4 5 6 7]
//获取全部数据
fmt.Println("arr[:] =", arr[:]) //[0 1 2 3 4 5 6 7]
//以下为Slice更多用法
s1 := arr[2:]
fmt.Println("s1 =", s1) //s1 = [2 3 4 5 6 7]
s2 := arr[:]
fmt.Println("s2 =", s2) //s2 = [0 1 2 3 4 5 6 7]
fmt.Println("After updateSlice(s1)")
updateSlice(s1) //Slice 将原有数组的数据修改掉了
fmt.Println(s1) //[100 3 4 5 6 7]
fmt.Println(arr) //[0 1 100 3 4 5 6 7]
fmt.Println("After updateSlice(s2)")
updateSlice(s2) //Slice 将原有数组的数据修改掉了
fmt.Println(s2) //[100 1 100 3 4 5 6 7]
fmt.Println(arr) //[100 1 100 3 4 5 6 7]
//对 Slice 再次进行 Slice 操作
fmt.Println("Reslice")
fmt.Println(s2) //[100 1 100 3 4 5 6 7]
s2 = s2[:5]
fmt.Println(s2) //[100 1 100 3 4]
s2 = s2[2:]
fmt.Println(s2) //[100 3 4]
//Slice 的扩展用法
fmt.Println("Extending slice")
arr[0], arr[2] = 0, 2 //将数据复原
fmt.Println("arr =", arr) //arr = [0 1 2 3 4 5 6 7]
s1 = arr[2:6]
s2 = s1[3:5] // [s1[3], s1[4]] //此处通过扩展可以取到后面一个值
fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n",
s1, len(s1), cap(s1)) //s1=[2 3 4 5], len(s1)=4, cap(s1)=6
fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n",
s2, len(s2), cap(s2)) //s2=[5 6], len(s2)=2, cap(s2)=3
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
//添加元素时如果超过cap,系统会重新分配更大的底层数组
//由于值传递 的关系,必须手动接受 append 的返回值
fmt.Println("s3, s4, s5 =", s3, s4, s5)
//s3, s4, s5 = [5 6 10] [5 6 10 11] [5 6 10 11 12]
// s4 and s5 no longer view arr.
fmt.Println("arr =", arr) //arr = [0 1 2 3 4 5 6 10]
}
func main() {
array()
slice()
}
切片(Slice)的扩展
通过下图可以更好的理解 Slice的扩展功能,扩展后 s2=[5,6]。
Slice可以向后扩展,但不能向前扩展
Slice的底层实现包含了三个变量,分别是
ptr :代表当前Slice第一个数据在原数组中的指针
len:代表当前Slice的长度
cap:代表向后扩展后的总数据
转载于:https://my.oschina.net/ruoli/blog/1815476
上一篇: go语言数组和切片的深度对比
下一篇: jdbc连接mysql出现问题解决