## Go 语言入门 -- 数组, 切片和 Map
按照以往开一些专题的风格, 第一篇一般都是 "从 HelloWorld 开始"
但是对于 Go, 思来想去, 感觉真的从 "HelloWorld" 说起, 压根撑不住一篇的篇幅, 因为 Go 的 HelloWorld 太简单了.
### 1, 简介
> Go 是什么?
**Go**(又称 **Golang**)是 [Google](https://baike.baidu.com/item/Google) 开发的一种[静态](https://baike.baidu.com/item/静态)[强类型](https://baike.baidu.com/item/强类型), 编译型, 并发型, 并具有垃圾回收功能的[编程语言](https://baike.baidu.com/item/编程语言).-- 摘自百度百科
> GitHub 地址
<https://github.com/golang/go>
> 官网地址
[https://golang.org](https://golang.org/)
> 中文网社区
[https://studygolang.com](https://studygolang.com/)
如果需要下载安装包, 可以进入 < https://studygolang.com/dl > 下载, 速度较快
<https://www.golangtc.com/>
> 关键字
简单, 学习曲线低, 天然高并发, 背景雄厚, 大厂拥抱
- ### 2, 环境搭建
- #### 下载安装
进入官网或者 < https://studygolang.com/dl > 下载对应系统的安装包(我的是 MacOS 系统)
下载成功后点击安装(无脑下一步即可)
#### 环境变量配置
打开命令行执行 sudo vi ~/.bash_profile 配置 GOROOT 和 GOPATH
注意: GOPATH 如果不配置, 默认在会在用户目录下新建 go 目录, GOPATH 相当于工作空间, 有点类似 Java 开发的 workspace.
配置完成执行 go version 出现类似
- ```
- go version go1.12.4 darwin/amd64
- ```
则表示安装成功
#### 开发工具
至于开发工具看个人喜好, 鉴于做 Java 开发使用的宇宙第一好用 IDE intellij idea 确实好用, 所以个人还是继续用 JetBrain 的产品 Goland 作为开发 IDE.
当然, 除此以外, 还有 Atom,VS code 等等.
下面开始进入正题, 说说 Go 语言中的数组, 切片和映射即 Map. 在此之前还需要介绍几个背景知识, 不然第一次看 Go 的语言可能有点懵~
- ### 背景知识
- #### 类型后置
不同于 Java,C++ 等很多语言, Go 采用类型后置的方式声明变量
比如 Java 中声明一个 int 的基本类型是这样的
- ```
- int a = 3;
- ```
而 Go 里面其中一种声明方式是这样的
- ```
- var a int
- a = 3
- ```
- #### 多样的赋值语句
Go 的声明和初始化方式丰富多样, 有点太丰富了, 听说 2.0 版本要稍微收收规范下
比如如下的方式是正确的
* 方式 1
- ```
- var a int
- a = 3
- ```
** 解读:** 初始化语句表明了 a 是一个 int 类型
然后才能对一个 int 类型进行赋值
* 方式 2
- ```
- var a = 3
- ```
** 解读:** 虽然没有明确表示这是一个 int, 但是 Go 可以根据后面的赋值推断出 a 的类型
* 方式 3
```
a := 3
```
** 解读:** 这是一种简单高效的初始化和赋值方式,`:=` 表示初始化一个变量 a 并同时对其赋值为 3
** 以下方式是不正确的 **
* 方式 1
```
var a
```
** 解读:** 基于这样的信息, a 没有赋值, Go 编译器是无法知道 a 的类型, 也无法对其进行初始化和赋值了
* 方式 2
- ```
- var a int
- a := 3
- ```
** 解读:** 虽然正确的声明了一个 int 类型的 a 变量, 但是下面的 `:=` 相当有重新声明了一个变量 a, 所以重复申明也会编译出错
有了上面两个背景知识储备, 加上自个儿在相关语言上面深厚的积累, 开始下面的讲解就没事问题了~
### 数组
数组几乎是每个语言必备的数据结构之一, Go 也不例外.
数组也有多种初始化和赋值方式
* 方式 1
- ```
- var arr [5]int // 注意这里必须要声明大小, 下面要讲的切片这里可以不用声明大小
- arr[0] = 0
- arr[1] = 1
- arr[4] = 4
- ```
* 方式 2
- ```
- var arr []int
- arr = make([]int, 4)
- ```
该方式通过 make 指定数组的大小, 这里表示数组容量为 4, 超过 4, 比如赋值如 `arr[4]=4`, 则会报错 `panic: runtime error: index out of range`
panic 相当于 Java 里面的 Exception
* 方式 3
- ```
- var arr [5]int{1,2,3,4,5}
- ```
* 方式 4
- ```
- arr := [5]int{1,2,3,4,5}
- ```
* 方式 5
- ```
- var arr [...]int{0:1, 3:4, 1:2} // x:y, 其中 x 表示 index,y 表示值,... 表示变长和 Java 中的变长函数一个道理
- ```
- ### 切片
切片有些语言里面可能没有这个名词, 我记得 Python 里面有, Java 里就没有.
切片可以看成是一种特殊的数组, 该种数组可以变长. 其生命和初始化方式也有多种
* 方式 1
- ```
- var s []int{1,2,3,4,5}
- s := []int{1,2,3,4,5}
- ```
* 方式 2
- ```
- s := make([]int, 3, 5) // 3 所在位置表示切片长度, 5 所在位置表示容量即最大可能存储的元素个数
- ```
** 注意:**`s[2]=2` 该赋值是合法的, 但是 `s[3]=3` 则会报错, 因为需要使用 append 追加元素, 类似
- ```
- s = append(s, 3) // 此时 len=4, cap=5
- s[3] = 10 // 对 s[3]重新赋值, 合法
- ```
另外如果赋值时, 切片长度没超过定义的切片的长度, 返回原来的切片地址, 如果超过了长度, 切片会扩容进行重新分配地址.
* 方式 3
- ```
- s := arr[1:3] // 表示截取数组一部分成为一个切片, 1 表示起始位置, 3 表示结束为止, 是一个左闭右开区间
- ```
- ### Map
map 就是键值对, 跟 Java 的没差
声明好初始化的方式如下
* 方式 1
- ```
- var m map[string]int // string 所在位置表示 key 的类型, int 所在位置表示 value 的类型
- ```
* 方式 2
- ```
- m := make(map[string]int, 5) // 5 所在位置表示 map 的容量
- ```
* 方式 3
- ```
- m = map[string]int{"jackie":1, "zheng":8}
- ```
- ### 共同点和差异点
* 数组, 切片和 Map 都可以通过 make 关键字进行初始化
* 数组, 切片和 Map 都支持在 `{}` 里面使用 `index:value` 进行初始化值
* 数组和切片差别在于数组必须声明数组容量, 即使是变长声明类型, 也必须列出具体数组元素
* 切片有 append 函数, 涉及到扩容等问题
### 下篇预告
1, 数组, 切片和 map 的遍历以, 切片扩容, map 根据 key 和 value 排序等
2,Go 和 Java 使用体验差异
如果您觉得阅读本文对您有帮助, 请点一下 "推荐" 按钮, 您的 "推荐" 将是我最大的写作动力! 如果您想持续关注我的文章, 请扫描二维码, 关注 JackieZheng 的微信公众号, 我会将我的文章推送给您, 并和您一起分享我日常阅读过的优质文章.
来源: https://www.cnblogs.com/bigdataZJ/p/array-slice-map.html