天天看点

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

Go语言提供了数组类型的数据结构。

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,类型可以是任意的原始类型例如×××、字符串或者自定义类型。

相对于去声明number0, number1, ..., and number99的变量,使用数组形式numbers[0], numbers[1] ..., numbers[99]更加方便且易于扩展。

数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为 0,第二个索引为 1,以此类推。

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:

<code>var variable_name [SIZE] variable_type</code>

以上为一维数组的定义方式。数组长度必须是整数且大于0。例如以下定义了数组balance长度为10类型为float32:

<code>var balance [10] float32</code>

<code>var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}</code>

初始化数组中{}中的元素个数不能大于[]中的数字。

如果忽略[]中的数字不设置数组大小,Go语言会根据元素的个数来设置数组的大小:

<code>var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}</code>

该实例与上面的实例是一样的,虽然没有设置数组的大小。

<code>balance[4] = 50.0</code>

以上实例读取了第五个元素。数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为0,第二个索引为1,以此类推。

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

数组元素可以通过索引(位置)来读取。格式为数组名后加中括号,中括号中为索引的值。例如:

<code>var salary float32 = balance[9]</code>

以上实例读取了数组balance第10个元素的值。

以下演示了数组完整操作(声明、赋值、访问)的实例:

Go 语言支持多维数组,以下为常用的多维数组声明方式:

<code>var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type</code>

以下实例声明了三维的整型数组:

<code>var threedim [5][10][4]int</code>

二维数组是最简单的多维数组,二维数组本质上是由一维数组组成的。二维数组定义方式如下:

<code>var arrayName [ x ][ y ] variable_type</code>

variable_type为Go语言的数据类型,arrayName为数组名,二维数组可认为是一个表格,x为行,y为列,下图演示了一个二维数组a为三行四列:

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

二维数组中的元素可通过a[ i ][ j ]来访问。

初始化二维数组

多维数组可通过大括号来初始值。以下实例为一个3行4列的二维数组:

访问二维数组

二维数组通过指定坐标来访问。如数组中的行索引与列索引,例如:

<code>int val = a[2][3]</code>

二维数组可以使用循环嵌套来输出元素:

如果向函数传递数组参数,需要在函数定义时,声明形参为数组。数组参数传递为值传递,如果要在函数内部修改数组的元素的值,需要传递数组指针。通常,函数的数组参数的声明有两种方式:

A、形参指定数组大小

B、形参不指定数组大小

数组使用实例:

Go语言切片是对数组的抽象。

由于Go数组的长度不可改变,Go中提供了一种灵活、功能强悍的内置类型切片("动态数组"),切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

可以声明一个未指定大小的数组来定义切片:

<code>var identifier []type</code>

使用make()函数来创建切片:

<code>var slice1 []type = make([]type, len)</code>

可以指定容量,其中capacity为可选参数。

<code>make([]T, length, capacity)</code>

len是数组的长度并且也是切片的初始长度。

<code>s :=[] int {1,2,3 }</code>

直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3,cap=len=3

<code>s := arr[:]</code>

使用数组arr的引用初始化切片s

<code>s := arr[startIndex:endIndex]</code>

将arr中从下标startIndex到endIndex-1下的元素创建为一个新的切片

<code>s := arr[startIndex:]</code>

缺省endIndex时将表示一直到arr的最后一个元素

<code>s := arr[:endIndex]</code>

缺省startIndex时将表示从arr的第一个元素开始

<code>s1 := s[startIndex:endIndex]</code>

通过切片s初始化切片s1

<code>s :=make([]int,len,cap)</code>

通过内置函数make()初始化切片s,[]int标识为其元素类型为int的切片

切片是可索引的,并且可以由len()方法获取长度。

切片提供了计算容量的方法cap()可以测量切片最长可以达到多少。

切片在未初始化前默认为nil,长度为0。

可以通过设置下限及上限来设置截取切片[lower-bound:upper-bound]。

切片在本质上是数组的视图。切片是一个数组片段的描述,包含了指向数组的指针、片段的长度和容量(片段的最大长度)。切片与底层数组的关系如下:

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

切片的内部实现如下:

Go语言开发(三)、Go语言内置容器Go语言开发(三)、Go语言内置容器

切片内部包含一个指向底层数组的某个位置的指针、切片长度信息、切片容量信息。

slice可以向后扩展,不可以向前扩展。

s[i]方式对切片数据进行引用不可以超越len(s),向后扩展不可以超越底层数组cap(s)。

如果想增加切片的容量,必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

append()函数可以相一个切片追加一个或多个元素。

copy(dest,src)函数可以将dest切片拷贝到src切片。

追加元素时,如果切片超越了cap,系统会为切片分配一个更大的底层数组,每次需要重新分配底层数组时,底层数组的容量会翻倍增长。

Ma是一种无序的键值对的集合。Map最重要的一点是通过key来快速检索数据。

Map是一种集合,可以对其进行迭代。Map使用hash表来实现,Map是无序的,无法决定返回顺序。

可以使用内建函数make,也可以使用map关键字来定义Map:

如果不初始化map,会创建一个nil的map。nil的map不能用来存放键值对。

获取元素:map[key]

key不存在时,获得value类型的初始值。

用value,ok := map[key]来判断是否存在key。

使用range遍历key,遍历key,value对,遍历不保证顺序。

使用len获得map的元素个数.

map使用哈希表,必须可以比较相等。

除了slice、map、function的内置类型都可以作为key。struct类型如果不包含slice、map、func字段可以作为key。

delete()函数用于删除集合的元素, 参数为map和其对应的key。

Go语言中range关键字用于for循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中,range返回元素的索引和索引对应的值,在集合中返回key-value对的key值。