这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
Go 语言上手 - 基础语言
简介
Go 的优点
高性能、高并发,不需要额外的高性能库
语法简单、学习曲线平缓,一周时间即可上手到实际开发
丰富的标准库,很高的稳定性和兼容性
完善的工具链,如编译、单元测试框架、代码格式化、包管理…
静态链接、部署很方便
快速编译,增量编译十分方便
跨平台,交叉编译也支持
垃圾回收
字节全面拥抱 Go 语言
由于 C++ 不太适合在线 Web 服务,且早期团队非 Java 背景,故而使用 Python ,后面由于性能问题开始转向 Go。
现在已经成为了字节内部占比最大的语言!
入门
开发环境
本地
-
安装 Golang
进入官网,或者进入 中文镜像网站
-
IDE
推荐 Vscode 、 Goland
基于云的开发环境
github 可以很方便地使用 gitpods.io 的在线编程环境来使用 golang
基础语法
hello world
·package 代表文件所属包,main 包是程序的入口。
import 导入各种包,fmt 是常用的控制输入输出格式化的包
变量
Golang 是一门强类型语言,每个变量都有它的类型
字符串在 Golang 中是内置类型
变量的声明有两种形式:
- 直接
var a = "initial",让程序自动推导类型;也可在变量后指定变量类型,如var b int = 1 - 使用 "变量名 := 值" 声明,如
f := float32(e)
常量声明直接 const c = 10,类型也是通过自动推导得到
判断语句
if 后面表达式无需加上括号,且必须后面加上大括号
循环
没有while、do while 循环,只有唯一的 for 循环。
for 后面啥也不加代表一个死循环,for 后面的三段任一都可以省略。
switch
switch 后面表达式可以不加括号
case 中不需要加 break
switch 可以使用任意的变量类型,甚至可以用来取代任意的 if else 语句:在 switch 后面不加任何变量,在 case 里面写条件分支,这样的代码比起多个 if else 会更有逻辑。
数组
数组是一个具有编号,且长度固定的元素序列,其声明方式如 var a[5]int
不过在真实业务中很少使用,因为其长度是固定的,更多使用的是切片
切片
切片不同于数组,可以任意更改长度,且支持更丰富的操作:
- 使用
make创建一个切片,s := make([]int, 3)j、或b = []int{1,2} - 像数组一样取值
- 使用
append追加元素( 注意要将结果赋值给原数组s = append(s, 2, 3))
Slice 原理: 存储一个长度和容量,加一个指向一个数组的指针,容量不够时自动扩容并返回新的 Slice (类似 c++ 中 vector)
拥有像 python 一样的切片操作,但不支持负数索引
map
可以使用 make 来创建一个空 map,这里需要指定 key 和 value 的类型
可以在 map 中存储或取出 键值对,也可以使用 delete 从里面删除键值对
Golang 的 map 是 完全无序的,遍历的时候是按照随机顺序
range
对于一个 slice 和 map ,可以使用 range 来快速遍历
range 遍历时候, 对数组会返回两个值: 索引 和 值; map 也会返回 key 以及 value,如果不需要,可以使用下划线来忽略
函数
Golang 中变量类型是后置的
Golang 函数原生支持返回多个值,实际业务逻辑代码中,几乎所有的函数都只返回两个值: 结果 & 错误信息
指针
支持的操作很有限,主要用途是 对于传入参数进行修改。
表示指针的 * 放在类型前面
取地址符与 cpp 一样,都是 &
结构体
结构体是带类型的字段的集合,可使用结构体名称去初始化一个结构体变量
构造的时候需要传入每个字段的初始值,也可以用键值对的方式去指定初始值(指定方式可以只对一部分字段进行初始化)
结构体支持指针,以避免拷贝开销
结构体方法
Golang 中可以为结构体定义一些方法,有一点类似其他语言中的类成员函数
方式是在 func 关键字后面加上括号传入结构体(或结构体的指针),从而可以通过 结构体直接去调用这个函数,结构体和结构体指针的区别在于后者能够使得修改生效
错误处理
在 golang 中,符合语言习惯的处理错误方法是:使用一个单独的返回值来传递错误信息
在函数的返回值类型里,后面加一个 error 就代表这个函数可能会返回错误
那么在函数实现的时候,成功则返回结果以及 nil,失败则返回 nil 和一个 error。
字符串操作
标准库 strings 中有很多常用的工具函数,如:
contains判断一个字符串里是否有另一个字符串count用于字符串计数index查找某个字符串的位置join连接多个字符串,且可设置连接符Repeat函数用于重复多个字符串replace用于替换字符串split用于分割字符串`ToLower用于字符转化小写- ….
字符串格式化
fmt 包中有很多字符串格式相关的函数,如 printf,与 cpp 不同,可以使用 %v 代替任意类型变量,另外可以使用 %+v 以及 %#+ 打印详细信息。
json 处理
对于一个已有结构体,只要保证每个字段的第一个字母是大写,即公开字段。那么,这个结构体就能用 JSON.marshaler 去序列化,变成一个 json 的字符串。
对于一个序列化字符串,可以用 json.unmarshaler 去执行反序列化到一个空的变量里去。
时间处理
golang 中最常用就是 time.now() 来获取当前时间,另也可以使用 time.date 来构造一个带时区的时间。
一个时间有多种方法来获取各个单位
可以使用 sub 对两个时间进行减法,得到一个时间段。
此外,可以使用 变量.Unix() 来获取时间戳(方便与某些系统交互)
数字解析
golang 中字符串与数字类型之间的解析都在 strconv 这个包下
我们可以用 parseInt 和 ParseFloat 来解析一个字符串
Atoi 可用于一个十进制字符串转成数字
itoA 可用于把数字转成呢个字符串
输入不合格,会返回 error
进程信息
在 golang 中,可以使用 os.Args 来获取程序执行时指定的命令行参数
os 包中包含很多可以对环境变量、系统设置等进行读取、修改的函数