数组,字符串,切片
笔记内容 是个人总结《Go语言高级编程》的学习笔记
基础的数据结构,只有在这些不满足的时候才会使用链表,map,结构体等数据结构。
数组,字符串,切片 有相同的内存结构,都是连续的内存块,因为在语法上的限制才有不同的表现,了解内存结构,可以更好的理解和使用它们
- 数组: 对应的连续的字节数组,可以修改内存数据,但是它是值类型,赋值和传参都是整体赋值
- 字符串:对应的连续字节数组,不可以修改内存数据,只读属性
- 切片: 用的最多,同样的连续字节数组,但是切片头部包含底层数据的指针,数据长度和容量信息,传参时候只需要传递这些信息,更加高效
数组
连续内存的数据类型的内存块,跟c语言不同的是,Go中的数组名是一个值类型,
- 在c语言中,数组名表示数组的首元素地址,也就是说数组名具有地址的概念
int a[10],*p;
p = a;
p = &a[0]; //做参数传递的时候,只是传递首地址
- 在go中,数组名表示的就是一个数组变量,并不是指向数组第一个元素的地址,在赋值或者传参的时候,传递的是整个数组,不够高效
a := [...]int {
1,2,3} //声明并初始化 a = {1,2,3}
func test(a [3]int){
...
}
test(a) //传递是整个数组
数组可以定义多种数组类型,看着挺好玩的
- 字符数组
var s1=[2]string{
"hello", "world"}
- 结构体数组
var line2 = [...]People.Student{
People.Student{
age : 30 , score :100}, People.Student{
age : 20 , score :100}}
- 函数数组
var decoder2 = [...] func (io.Reader) (image.Image, error){
png.Decode,
jpeg.Decode,
}
- 接口数组
var unknown2 = [...] interface {
}{
123 , "你好" }
- 管道数组
var chanList = [2] chan int{
}
字符串
字符串是不可改变 字符序列,Go语言中字符串的定义是一个结构体
type StringHeader struct {
Data uintptr
Len int
}
个人理解: 在栈上开辟一个结构体内存,Data 指向静态区的字符常量,Len表示字符长度,也就是每个字符串的底层结构也是一个结构体,书中也说字符数组本质也是结构体数组
迷惑未解:
func testString() {
string1 := [...]string{
"helloooooooo", "worlddddddd"}
fmt.Printf("arr = %p, string1[0] =%p,string1[0] =%s,len string1[0] = %d,string[1] = %p", &string1, &string1[0], string1[0], len