go语言学习之数组、map

任何语言都提供了数组这一特殊的存储结构,各有各的好处。go语言的数组和常规编程语言的数组差不多,只不过它还提供了一个称之为切片的容器(你可以把它理解为可变长的数组),切片的定义方法为:slice []int,仔细看跟数组定义的方式一样,只不过是它没有确定的大小,go语言中称这种变量为切片。切片我们需要了解三个东西:prt是一个指针,存储当前对切片操作的最后一次位置或者当前位置,len是切片的长度,cap是允许扩展的最大长度。乍一看和c++的链表极为相似啊!我们当然可以将它理解为c++的链表!并且go语言提供的插入删除超级简单!不像c++语言那样要连接表头表尾什么的。一个append就能搞定。删除也很容易,稍后将详细介绍。本篇博客构成:数组介绍、切片介绍、map介绍。

一、数组

1.定义形式为:

(1) var arry1 [5] int 

(2)arryy2:= [5] int {1,2,3,4,5}

(3)arry3:= [...] int {1,2,3,4,5}

第三种定义方法中的三个点表示是可变的,这种方式非常实用,包括在以后的循环也可以这么用。另外可以用下划线_来省略不想用的变量,比如某些必须要两个参数的地方,可以加_省略其中的一个。

2.遍历:

数组的遍历一般都是使用for循环或者range。

(1)传统的for循环:

(2)range:

range有一个好处就是它可以同时获得下标和对应的值,在map中range也发挥着重大的作用。

3.值传递

前一篇博客讲到go语言的数组是值形式,意味着它可以作为函数的参数来使用。如:func variableSum(array [5] int),那么你要用这个函数,传进来的数组大小必须是为5,其它大小则报错,因为它是一个值。那你可能会问了这样多不方便啊,我要是想用其它大小的还得重写一个一模一样的多麻烦。所以就需要一个可变的数组来作为参数,这就是后面要提到的切片。

二、切片Slice

切片有点像链表,大家都是长度可变,但切片的操作更简单。切片我们可以看作从数组切出某一片,因此比较容易理解的说法就是把这个切片看作数组的一个view。下面将深入分析这个切片到底是什么。

1. 表示形式:sslice [] int (slice是go语言的保留字千万不能用作定义变量)为什么不说定义形式,这个写法是切片用作函数的参数的时候才这么写。平时我们要用的时候这样定义:s:=array[1:6],这里要重点说一下这个区间,go语言的这种区间包含起始不包含结尾。也就是说切片的范围是原数组的1-5(下标0开始)共5个元素,并不包含下标为6的元素。array[1:]表示从1号元素到数组尾部,array[:6]表示从头部元素开始到6号元素。所以我们可以通过这种切片还实现某个数组的元素删除而避免元素移动或者合并两个数组。

2.定义形式:

(1)var s [] int

  (2)s:=make([]int,len,cap)第一个参数的切片的类型,第二个是切片的长度,第三个是cap扩展长度,切片允许扩展的长度不能超过cap。

这里简单题下切片的扩展规则吧,比如现在创建了一个切片s:=make([]int,8,128)。初始分配的空间是len,并不少cap,cap是允许分配的最大空间。扩展规则是这样的:当切片空间用满的时候扩展为原来的两倍,所以这个切片扩展的过程是:8,16,32,64,128。len后面的cap地址空间对程序员不可见。 

3. 切片的基本操作

(1)添加元素

slice提供了append这个函数用于向切片添加元素,添加的位置当前是在末尾了啊。暂时没有提供任意位置插入的,不过你可以从你想要插入的地方切开,然后再添加,再append后面被切开的。append不单单是添加一个元素,可以添加一个切片。下面看个append的例子:

go语言学习之数组、map_第1张图片go语言学习之数组、map_第2张图片

现在我想在元素3和4之间插入一个300,像我上面说的那样,将S分成两个切片S1,S2,在S1添加300后再加上S2即可。具体看代码:

go语言学习之数组、map_第3张图片

理想的操作是这样的,但是发现出现了两个300而100没了!这是怎么回事呢!!切记切片是直接对原数组进行操作的,如果你没有进行拷贝操作!那这里是怎么一回事呢?当S1插入300后S变成了2 3 4 5 300 200 ,而我们的S2切片是4号和5号的位置,所以S2变成了300 200 ,append 的时候我们看到了两个300。如何避免这种情况呢?slice还提供了一个copy函数,我们将第一次取的S2 copy一份就好了。copy函数:copy(dst,src)dst接收拷贝的变量,src是拷贝的源文件。

go语言学习之数组、map_第4张图片

将第一次取到的S2拷贝一份给S3即可。这个错误也是我在写博客的时候遇到的,之前没认真看书,所以不知道slice直接对底层数组进行操作。另外go语言提供了垃圾回收机制,不使用的内存会被回收,所以不用担心内存溢出问题。

(2)删除元素

删除元素的操作和插入的其实很相似,将指定区间的切片加起来就好了。拿上面的例子来说吧,我现在要将300删除。

go语言学习之数组、map_第5张图片

很简单,没有多余的操作,时间复杂度很快。

三、map

go语言的map是基于哈希表实现的。

1.定义形式:

声明:var map1 map[key type] value type  

创建:map1:=make(map[keytype]valuetype)(就相当于申请开辟一块内存)

常见的还有下面的方式:

go语言学习之数组、map_第6张图片

2.map的赋值:

map1["test1"] =12;

map1["key"] = value1

3.获取map的元素:

value1 = map1[key],这种方式有个问题,就是不一定能判断map1里面是否value1这个值,解决的办法是:map获取元素的时候返回了两个值,其中有一个字段是ok,ok是保留字,直接用就行,如果为ok为true则包含该值,否则不包含。

4.map的遍历:

map的遍历可以用常规的for循环也可以用range。获得map的长度可以用len()函数。这里展示range的用法:

go语言学习之数组、map_第7张图片

5.map的删除

map的删除比较简单,go直接提供了delete函数。delete(map,key)

go语言学习之数组、map_第8张图片

博客有些地方写的不是很好,欢迎留言讨论,我也是新手上路~

你可能感兴趣的:(go语言学习之数组、map)