Go语言学习4:Slices

来源:互联网 发布:不可使用公式型数据 编辑:程序博客网 时间:2024/05/03 04:24

Slice是Go语言提供的一种方便并且高效的有序数据类型,就和其他语言的数组类似,但是又有一些其他的特性。

Go数组:

因为Slice是建立在Go数组的抽象层上的,所以,要学习Slice,我们先来看一下Go语言的数组:

一个数组定义了一个具有特定长度和数据类型的数据。例如:【4】int 就代表了一个有4个int类型的数组。数组的大小是确定的,数组的长度是数组类型的一部分(【4】int和【5】int是完全不同的类型)。数组可以像其他语言那样索引,s【n】能够访问第n个元素:

var a [4]inta[0] = 1i := a[0]// i == 1
数组不需要明确的初始化,没有初始化的项,将用0作为默认值

// a[2] == 0, the zero value of the int type
【4】int的内存结构如下图:


Go语言的数组是值定义的,而不是指针。一个数组变量就代表了整个数组,而不是一个指向第一个数组元素的指针(像c语言那样)。这就意味着,当需要传递一个数组的时候,我们应该传递这个数组的整个内容,也就是拷贝这个数组的整个内容。(为了避免拷贝的麻烦,我们可以传递一个指向数组的指针,但是需要注意的是:这样做了之后,这个指针就仅仅是一个指针而已,而不是一个数组)


一个字符串数组可以这样定义:

b := [2]string{"Penn", "Teller"}
或者,可以让编译器帮我们统计元素的个数:

b := [...]string{"Penn", "Teller"}
这两种方法都是等价的。

Slices:

数组拥有自己的内存空间,这个内存空间是一个整体,不能分割的。因为这个原因,Go中用了大量的Slices而不是数组。
声明一个slices的方法:
【】T,T是slice中元素的类型,和数组不同,slice是不需要指定长度的。
声明一个字符类型的slice的方法和声明一个数组差不多,只是不指定元素个数而已:
letters := []string{"a", "b", "c", "d"}

slice也可以用Go内部库函数make来创建,make是具有签名功能的:

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

T表示元素的类型,make函数有3个参数,T元素的类型,len长度,cap容量(cap可选)。当make被调用的时候,make分配一下数组并且返回一个根据这个数组生产的slice。如果不填写cap,那么默认的情况下cap=len,一种简洁的make的写法是:

s := make([]byte, 5)

可以用Go的库函数,len和cap来获取slice的len和cap:

len(s) == 5cap(s) == 5

slice的0值为nil,如果一个slice等于nil,那么len和cap都会返回0.

我们同样可以用一个已经存在的数组或者slice来创建一个新的slice,例如:

a :=b【n:m】,表示a取b中从n到m-1的元素。

例如:

b := []byte{'g', 'o', 'l', 'a', 'n', 'g'}// b[1:4] == []byte{'o', 'l', 'a'}, sharing the same storage as b

获取Slice片段的时候,默认的开始值是0,默认的结束是该slice的长度,例如:

b := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
b[:2] == []byte{'g', 'o'}b[2:] == []byte{'l', 'a', 'n', 'g'}b[:] == b

同样的,slice也可以用数组来创建:

x := [3]string{"Лайка", "Белка", "Стрелка"}s := x[:] // a slice referencing the storage of x

slice的存储结构:

一个slice描述了一个数组的片段,一个slice包括:指向数组的指针,该段的长度,容量(段的最大长度)

s := make([]byte, 5)的存储结构如下:


再次明确一下,len是slice中item的个数,cap是slice所指向的数组的长度(从slice所指向的开始的位置开始,直到数组结尾),例如:

s = s[2:4]

slice的基础上创建新的slice,并不是做赋值操作,而是创建了一个新的指向相同数组的slice,例如:

d := []byte{'r', 'o', 'a', 'd'}e := d[2:] // e == []byte{'a', 'd'}e[1] = 'm'// e == []byte{'a', 'm'}// d == []byte{'r', 'o', 'a', 'm'}


















原创粉丝点击