Go语言中,数组、字符串、切片是密切相关的数据结构。

简介

Go语言的赋值和函数传参,除了闭包是引用的方式对外部变量访问外,其他赋值和函数传参都是 值传递的方式。
它们底层原始数据有相同的内存结构。

  • 数组是一种值类型,数组本身的赋值和函数传递都是以整体复制的方式处理的。
  • 字符串底层数据对应的是字节数组,但是有只读属性;字符串赋值只是复制了数据地址和对应的长度,不会导致底层数据的复制。
  • 切片的结构和字符串类似,但是解除了只读限制。
    切片的底层数据对应数据类型的数组,但是每个切片有独立的长度和容量信息;
    切片的赋值和函数传参是将切片头信息部分按值传递。切片头部包含底层数据的指针,它的赋值不会导致底层数据的复制。

数组

数组的长度是数组类型的组成部分。不同长度的数组因为类型不同无法直接赋值。因此Go语言中很少直接使用数组。
一个数组变量就是整个数组,而不是指向第一个元素的指针,
长度为零的数组,在内存中不占用空间。可以用来管道同步(但是更倾向于匿名结构体)。
数组类型时切片和字符串等结构的基础。

字符串

字符串长度不是字符串类型的一部分。
字符串其实是一个结构体,由底层字节数组+字符串的字节长度组成。地层结构在reflect.StringHeader结构体中定义,字符串的复制也是该结构体的复制。
可以将字符串数组看成是结构体数组。
字符串支持切片操作,但是是只读的。
rune只是int32的别名,并不是重新定义的类型。

切片

切片结构:reflect.SliceHeader结构(Data Len Cap)
在开头追加成员一般都会导致内存的重新分配,而且会导致已有元素全部复制一遍:a=append([]int{1,2,3},a…)
可以用copy+append来防止中间插入时创建临时切片

a=append(a,0)
 copy(a[i+1:],a[i:])//a[i:]后移一个单位
 a[i]=x//设置插入的位置