欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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可以向后扩展,但不能向前扩展

Go语言中数组和切片的用法

 

Slice的底层实现包含了三个变量,分别是 

ptr :代表当前Slice第一个数据在原数组中的指针

len:代表当前Slice的长度

cap:代表向后扩展后的总数据

 

Go语言中数组和切片的用法

 

 

转载于:https://my.oschina.net/ruoli/blog/1815476