最新消息:比度技术-是关注云计算、大数据、分布式存储、高并发、高性能、人工智能等互联网技术的个人博客。

golang 切片 数组

编程开发 bidu 185浏览

Go的数组是值语义。一个数组变量表示整个数组,它不是指向第一个元素的指针(不像 C 语言的数组)。 当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。 (为了避免复制数组,你可以传递一个指向数组的指针,但是数组指针并不是数组。)

切片可以使用内置函数 make 创建,函数签名为:

func make([]T, len, cap) []T

其中T代表被创建的切片元素的类型。函数 make 接受一个类型、一个长度和一个可选的容量参数。 调用 make 时,内部会分配一个数组,然后返回数组对应的切片。

当容量参数被忽略时,它默认为指定的长度。下面是简洁的写法:

s := make([]byte, 5)

可以使用内置函数 len 和 cap 获取切片的长度和容量信息。

len(s) == 5

cap(s) == 5

slice切片的操作——切片的追加、删除、插入等

声明变量,go自动初始化为nil,长度:0,地址:0,nil

切片的零值为 nil 。对于切片的零值, len 和 cap 都将返回0。

切片也可以基于现有的切片或数组生成。切分的范围由两个由冒号分割的索引对应的半开区间指定。 例如,表达式 b[1:4]创建的切片引用数组 b 的第1到3个元素空间(对应切片的索引为0到2)

一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度, 和容量(片段的最大长度)。

长度是切片引用的元素数目。容量是底层数组的元素数目(从切片指针开始)

切片操作并不复制切片指向的元素。它创建一个新的切片并复用原来切片的底层数组。 这使得切片操作和数组索引一样高效。因此,通过一个新切片修改元素会影响到原始切片的对应元素。

切片增长不能超出其容量。增长超出切片容量将会导致运行时异常,就像切片或数组的索引超 出范围引起异常一样。同样,不能使用小于零的索引去访问切片之前的元素

要增加切片的容量必须创建一个新的、更大容量的切片,然后将原有切片的内容复制到新的切片。 整个技术是一些支持动态数组语言的常见实现。下面的例子将切片 s 容量翻倍,先创建一个2倍 容量的新切片 t ,复制 s 的元素到 t ,然后将 t赋值给 s :

t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0

for i := range s {

t[i] = s[i]

}

s = t

循环中复制的操作可以由 copy 内置函数替代。copy 函数将源切片的元素复制到目的切片。 它返回复制元素的数目。

func copy(dst, src []T) int

copy 函数支持不同长度的切片之间的复制(它只复制较短切片的长度个元素)。 此外, copy 函数可以正确处理源和目的切片有重叠的情况。

使用 copy 函数,我们可以简化上面的代码片段:

t := make([]byte, len(s), (cap(s)+1)*2)

copy(t, s)

s = t

切片扩容

一个常见的操作是将数据追加到切片的尾部。下面的函数将元素追加到切片尾部, 必要的话会增加切片的容量,最后返回更新的切片:

func AppendByte(slice []byte, data …byte) []byte {

m := len(slice)

n := m + len(data)

if n > cap(slice) { // if necessary, reallocate

// allocate double what’s needed, for future growth.

newSlice := make([]byte, (n+1)*2)

copy(newSlice, slice)

slice = newSlice

}

slice = slice[0:n]

copy(slice[m:n], data)

return slice

}

下面是 AppendByte 的一种用法:

p := []byte{2, 3, 5}

p = AppendByte(p, 7, 11, 13)

// p == []byte{2, 3, 5, 7, 11, 13}

 

func append(s []T, x …T) []T

append 函数将 x 追加到切片 s 的末尾,并且在必要的时候增加容量。

如果是要将一个切片追加到另一个切片尾部,需要使用 … 语法将第2个参数展开为参数列表。

转载请注明:比度技术-关注互联网技术的个人博客 » golang 切片 数组