这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
go语言的特点
- 1.高性能,高并发
- 2.语法简单,学习路线平缓
- 3.丰富的标准库
- 4.完善的工具链
- 5.静态链接
- 6.快速编译
- 7.跨平台
- 8.垃圾回收
三大特点:
-
开发效率高
- 上手比较快——仅仅只有25个关键字
- 编译速度比较快
- 运维部署比较容易
- 不要额外安装像java的jdk或者js的node这样的运行环境
- 构建好之后只需一个可执行文件
-
高并发
- 语言层面就支持高并发,拥有goroutine协程机制
- 轻量级,比线程更轻量级
- 协程和线程的主要区别是它将不再被内核调度,而是交给了程序自己,而线程是将自己交给内核调度,所以也不难理解golang中调度器的存在。
- 协程没有线程的上下文切换消耗。协程的调度切换是用户手动切换的,因此更加的灵活。用户空间线程,有原子操作性。
- 协程:用户态,轻量级线程,栈MB级别;线程:内核态,线程跑多个协程,栈KB形态。
- 可以产生大量的线程
- 轻量级,比线程更轻量级
- 进程是系统分配资源的最小单元,线程是cpu调度的最小单元
- 语言层面就支持高并发,拥有goroutine协程机制
-
性能高
- 运算性能是java的1.5倍左右,运行空间是java的几十分之一,启动时间是java的几十分之一,并发量是java的上千倍
- 从性能上不如c语言,但是语法上要比c语言要更加优化一些。c语言是纯过程性的语言,申请内存和分配内存都需要手工处理,而go语言支持简单的自动化GC
其他:
go语言的特点,适合微服务云平台
go的设计理念就是简单,表达方式只有一种;正交性,代码耦合度大
2.2 基础语法
2.2.1Hello World
在编译器里面把鼠标悬浮在代码上,可以看到每一个函数的文档。
也可以进入pkg.go.dev,在后面加报名,看这个包的在线文档,从里面挑选需要的函数使用
2.2.2变量
go语言常见变量:字符串、证书、浮点型、布尔型
声明方式:var name = "" ; :=
常量就是把var改成const,常量没有确定的类型,会根据使用的上下文来自动确定类型
2.2.3if else
- if后面没有括号
- if后面必须接大括号,不能和if里面的语句同一行
2.2.4循环
- 只有for循环,使用break/continue跳出
2.2.5switch
- 可以使用任意的变量类型,可以用来取代任意的if else语句;switch后面可以不加任何变量,然后再case条件里写条件分支
- 不需要加break,switch后面变量不需要括号
2.2.6数组
一个具有编号且长度固定的元素序列,实际很少使用
2.2.7Slice
切片可以任意更改长度,可以用make来创建一个切片想数组一样去取值,使用append追加元素。需要把append的结果赋值给袁数组。
slice结构存储了一个长度和容量和指向一个数组的指针,在容量不够的时候会2倍扩展容量(当前切片长度<1024),25%扩容(>25%),一般而言,但是并不准确。
2.2.8map
哈希或者字典
1 声明&默认值
var m map[string]string
map的声明的时候默认值是nil ,此时进行取值,返回的是对应类型的零值(不存在也是返回零值)。
// bool 的零值是false
var m map[int]bool
a, ok := m[1]
fmt.Println(a, ok) // false false
// int 的零值是0
var m map[int]int
a, ok := m[1]
fmt.Println(a, ok) // 0 false
2 初始化
声明之后必须初始化,才能使用。
m2 := map[string]int{"one":1,"two":2}
var m3 = map[string]int{"one":1,"two":2}
golang的map是完全无序的,遍历的时候不会按照字母顺序,也不会按照插入顺序输出而是随机顺序
2.2.9 range
对于一个slice或者一个map可以使用range进行快速遍历
range遍历的时候,对于数组会返回两个值,第一个是索引,第二个是对应位置的值。不需要索引的话可以用下划线来忽略。
m := map[string]int{"one":1,"two":2}
for k,v := range m{
fmt.Println(k, v) //two 2;one 1
}
for k,_ := range m{
fmt.Println("key",k) //key two;key one
}
2.2.10函数
golang中变量类型是后置的,golang中的函数原生支持返回多个值。一般最后一个值是错误信息。
2.2.11指针
*和& 一般是拷贝要想传递使用&进行类型匹配
2.2.12结构体
结构体是带类型的字段的集合。可以用结构体名称去初始化一个结构体变量,构造的时候需要传入每个字段的初始值。也可以使用键值对的方式去指定初始值,对一部分的字段进行初始化。
- 同样的结构体也能支持指针,实现对于结构体的修改,避免大结构体的拷贝开销
2.2.13结构体方法
为结构体定义一些方法,类似类成员函数
实现结构体也有两种写法,一种是带指针,一种是不带指针
2.2.14错误处理
使用一个单独的返回值来传递错误信息。
2.2.15字符串操作
2.2.16字符串格式化
使用%v可以打印任何类型的变量,而不需要区分数字字符串
可以使用%+v,%#v打印更详细的内容
2.2.17Json处理
go语言里面的JSON操作非常简单,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串。 序列化之后的字符串也能够JSON.unmarshaler去反序列化到一个空的变量里面。 这样默认序列化出来的字符串的话,它的风格是大写字母开头,而不是下划线。我们可以在后面用json tag等语法来去修改输出JSON结 果里面的字段名。
2.2.18时间处理
2.2.19数字解析
strconv包——string convert
使用parseInt,parseFloat解析字符串
Atoi把一个十进制字符串转成数字,可以用itoA把数字转成字符串
2.2.20进程信息
课后作业
- 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现
var guess int
_, err := fmt.Scanf("%d", &guess)
- 修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持
可以使用火山翻译,百度和网易尝试失败,只能固定单词求解
curlconverter.com/#go 将copy的cURL进行go语言代码的解析
oktools.net/json2go 将返回的payload的值,生成golang的结构体
- 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度
var wg sync.WaitGroup
wg.Add(1)
go func() {
query(word)
wg.Done()
}()
wg.Add(1)
go func() {
huoshan(word)
wg.Done()
}()
wg.Wait()
参考
课后作业 -《Go 语言上手-基础语言》
三大特点整理自之前看过的go语言介绍视频