Go语言中的数组、切片和字符串
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)
输出结果:(数组类型指定了长度,而切片类型没有)
关于切片的使用:
切片可以使用下标直接为切片中的某一位置赋值,但前提是此位置必须已被使用
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语言内置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:下标越界
运行结果:
---------------------------------------------------------------------------------------------------
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)
字符串类型的遍历:
使用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)
可以看出使用for range遍历字符串时,会默认将byte(int8)类型转化为rune(int32)类型,因为Go语言默认编码为UTF-8,是一种变长编码。
PS:byte数组每个元素存储的均为元素的ASCII码,因此当byte数组中存储的为字符时,保存的也是字符的ASCII码。
执行byte数组向string类型的强制转换时,需要注意byte数组中实际数值所表示的字符是什么
上一篇: Incorrectsyntaxnear's'
下一篇: go语言数组和切片的深度对比