AI智能
改变未来

Go的100天之旅-06数组和Slice

文章目录

  • 数组
  • Slice

数组

Go

的数组和其它语言基本上一样,是长度固定的特定类型元素组成的序列,这基本上是所有语言数组的特性。和其它语言相比差异主要在声明和初始化的写法上,下面是简单声明一个数组:

var a [5]intfmt.Println(a[0])fmt.Println(fmt.Println(a[len(a)-1]))

上面的

a

是一个长度为

5

的整数数组,如果没有给定初始值它里面的元素默认值是

0

Go

数组的下标是从0开始的,

len

函数返回数组中元素的个数。我们可以在声明数组的时候初始化它的值:

var m [3]int = [3]int{1, 2, 3}var n [3]int = [3]int{2, 3}

这里的

m

n

都是长度为

3

的数组,

m

对应的值是

1, 2, 3

而由于

n

初始化的时候只有

2

个值,因此它里面的值是

2, 3, 0


如果采用简单声明

:=

的方式声明一个数组,可以指定数组的大小,也可以不指定大小这时它会根据初始化值的个数来确定:

a := [10]int{} //元素都为0b := [...]int{1, 2} //长度为2

Go

也可以直接指定一个索引和值,来初始化,如果声明的时候长度不指定,那最大的索引加

1

就是数组的长度:

a := [10]int{1:2} // 长度10,a[1] = 2 其它为0b := [...]int{1:2, 10:1} //长度11,a[1] = 2 a[10] = 1其它为0

数组

a

长度声明是

10

,只给了索引

1

的值为

2

,其余都为

0

。数组

b

声明的时候索引

1

2

10

1

,它的长度是

11

修改数组中某个索引的值方式和其它语言一样:

a := [10]int{}a[0] = 10

数组的类型是由元素的类型和长度共同决定的,

[3]int

[4]int

是两种不同的数组类型。因此:

a := [3]int{1, 2, 3}a = [4]int{1, 2, 3, 4}

编译的时候会报错,而:

a := [3]int{1, 2, 3}a = [3]int{4, 5, 6}

是正确的

Slice

上面说的数组长度是固定,使用的时候不是很灵活,

slice

的长度是可变,简单声明一个未初始化的

slice

var a []intprint(len(a))print(cap(a))

slice

也可以利用

len

返回它的长度,刚才声明的

slice

长度为

0

。除了长度

slice

还有一个容量

cap

的概念,用

cap

可以返回它的容量。长度不能超过它的容量。slice的声明也可以用

make

,用

make

声明可以指定容量和可以不指定容量,这时容量和长度一致:

a := make([]int, 10) //长度为10,容量为10a := make([]int, 10, 12) //长度为10 容量为12

slice

可以进行切片操作

slice[i:j]

,创建一个新的

slice

,新的

slice

范围是原来

slice

下标

i

j-1

,也可以不指定下标

slice[:j]

则是默认从

0

j-1

,同理如果

slice[i:]

就是从

i

到最后一个元素,下面是一个简单的例子:

a := []int {1, 2, 3, 4, 5}b = a[1:2]c = a[:2]d = a[1:]

需要注意的是切片操作

slice[i:j]

j

可以大于

slice

的长度,只要它小于容量

刚才一直讲到容量,那它到底有什么实际意义呢?开始

slice

的时候说过它长度是可变的,哪怎么改变了?通过

append

就可以对

slice

追加元素,这时容量就有作用了,如果append的时候当前长度小于容量,那

slice

不会扩大容量,也不会申请新的空间,而是在原来的基础上把长度加

1

就行了,如果容量等于长度,则会扩容,扩容会申请新的空间。

package mainfunc main() {a := make([]int, 10, 11)a = append(a, 1)println(len(a), cap(a)) // 11 11a = append(a, 1)println(len(a), cap(a)) // 12 12}
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Go的100天之旅-06数组和Slice