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

Go语言中的数组、切片和字符串

程序员文章站 2024-01-29 22:50:46
...

Go语言数组的定义方式:
var 数组名称 [数组长度]数组类型
数组名称 := [数组长度]数组类型{赋值}

切片即可变长度的数组,与数组不同的是不需要指定数组长度:
var 数组名称 []数组类型
数组名称:=[]数组类型{赋值}

----------------------------------------------------------------------------------------------
本次主要讨论byte类型的数组。byte类型本质上是int8类型,每个byte占1个字节;
关于数组的创建:

	var array1 [4]byte //先声明后赋值
	array1[0] = 1 //使用数组
	var array2 = [4]byte{1, 2, 3} //声明时赋值
	var array3 = array2[1:2]      //基于数组创建切片
	fmt.Printf("%T %T %T\n", array1, array2, array3)

	bytes := [4]byte{0, 1, 2, 3} //创建数组
	bytes2 := []byte{0, 1, 2, 3} //创建切片
	bytes3 := make([]byte, 4)    //创建切片,默认有四个元素,填充默认值
	//验证上面创建语句生成的变量类型
	fmt.Printf("%T %T %T\n", bytes, bytes2, bytes3)

输出结果:(数组类型指定了长度,而切片类型没有)
Go语言中的数组、切片和字符串
关于切片的使用:
切片可以使用下标直接为切片中的某一位置赋值,但前提是此位置必须已被使用

	bytes := make([]byte, 4, 10)//定义一个byte类型默认元素个数为4、容量为10的切片
	fmt.Printf("类型:%T  使用长度:%d  容量:%d\n", bytes, len(bytes), cap(bytes))

	fmt.Println("直接访问已使用部分的元素:", bytes[3])
	fmt.Println("直接访问未使用部分的元素:", bytes[4])//数组下标越界

Go语言中的数组、切片和字符串
Go语言内置append,传入参数为切片和不定参数,返回修改后的切片,且append的返回值必须被接收:

	//验证根据数组创建的切片是否共享同一块内存
	arr := [4]byte{1, 2, 3, 4}//创建一个数组
	var slice = arr[:] //根据数组生成一个切片
	fmt.Println(&arr[0], " ", &slice[0])//输出数组和切片的起始元素地址
	//修改数组中的第三个元素 观察切片相应位置元素是否改变
	arr[2] = 10
	fmt.Println(arr, " ", slice)
	/************************************/
	//验证append函数作用原理
	fmt.Println("验证append增长策略")
	fmt.Println("当前slice地址、元素数量、容量  ", &slice[0], len(slice), cap(slice))
	//研究传入的slice和返回的slice的关系
	//元素数量大于容量时 重新分配内存
	fmt.Println("超出容量 重新分配内存 原容量*2")
	newSlice := append(slice, 5)
	fmt.Println("元素超出容量,原slice的地址,元素数量,容量  ", &slice[0], " ", len(slice), " ", cap(slice))
	fmt.Println("元素超出容量,新slice的地址,元素数量,容量  ", &newSlice[0], " ", len(newSlice), " ", cap(newSlice))
	//当元素数量小于等于容量时 两者共享同一块内存  原slice不变 返回的slice元素数量加一
	newSlice2 := append(newSlice, 6, 7, 8)
	fmt.Println("元素未超出容量,原slice的地址,元素数量,容量  ", &newSlice[0], " ", len(newSlice), " ", cap(newSlice))
	fmt.Println("元素未超出容量,原slice的地址,元素数量,容量  ", &newSlice2[0], " ", len(newSlice2), " ", cap(newSlice2))
	fmt.Print(newSlice[6]) //panic:下标越界

运行结果:
Go语言中的数组、切片和字符串
---------------------------------------------------------------------------------------------------
string类型的底层是一个byte类型的数组,string类型和数组之间不能强制转换,但是string和切片之间可以强制转换:

	//array := [4]byte{'0', '1', '2', '3'}
	slice := []byte{'0', '1', '2', '3'}
	//arrToStr := string(array) //报错 cannot convert array (type [4]byte) to type string
	sliceToStr := string(slice)
	strToByte := []byte(sliceToStr)
	fmt.Printf("%s %v", strToByte, sliceToStr)

Go语言中的数组、切片和字符串
字符串类型的遍历:
使用for range遍历:

	s := "I love you 中国"
	for _, value := range s {
		fmt.Printf("%T %v %c\n", value, value, value)
	}
	fmt.Println("All English")
	s2 := "I love you"
	for _, value := range s2 {
		fmt.Printf("%T %v %c\n", value, value, value)

Go语言中的数组、切片和字符串
可以看出使用for range遍历字符串时,会默认将byte(int8)类型转化为rune(int32)类型,因为Go语言默认编码为UTF-8,是一种变长编码。

PS:byte数组每个元素存储的均为元素的ASCII码,因此当byte数组中存储的为字符时,保存的也是字符的ASCII码。
执行byte数组向string类型的强制转换时,需要注意byte数组中实际数值所表示的字符是什么