why Go | 青训营笔记

76 阅读6分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

go语言的特点

  • 1.高性能,高并发
  • 2.语法简单,学习路线平缓
  • 3.丰富的标准库
  • 4.完善的工具链
  • 5.静态链接
  • 6.快速编译
  • 7.跨平台
  • 8.垃圾回收

三大特点:

  • 开发效率高

    1. 上手比较快——仅仅只有25个关键字
    2. 编译速度比较快
    3. 运维部署比较容易
      • 不要额外安装像java的jdk或者js的node这样的运行环境
      • 构建好之后只需一个可执行文件
  • 高并发

    1. 语言层面就支持高并发,拥有goroutine协程机制
      • 轻量级,比线程更轻量级
        • 协程和线程的主要区别是它将不再被内核调度,而是交给了程序自己,而线程是将自己交给内核调度,所以也不难理解golang中调度器的存在。
        • 协程没有线程的上下文切换消耗。协程的调度切换是用户手动切换的,因此更加的灵活。用户空间线程,有原子操作性。
        • 协程:用户态,轻量级线程,栈MB级别;线程:内核态,线程跑多个协程,栈KB形态。
      • 可以产生大量的线程
    2. 进程是系统分配资源的最小单元,线程是cpu调度的最小单元
  • 性能高

    1. 运算性能是java的1.5倍左右,运行空间是java的几十分之一,启动时间是java的几十分之一,并发量是java的上千倍
    2. 从性能上不如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

  1. if后面没有括号
  2. if后面必须接大括号,不能和if里面的语句同一行

2.2.4循环

  1. 只有for循环,使用break/continue跳出

2.2.5switch

  1. 可以使用任意的变量类型,可以用来取代任意的if else语句;switch后面可以不加任何变量,然后再case条件里写条件分支
  2. 不需要加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字符串操作

image.png

2.2.16字符串格式化

image.png 使用%v可以打印任何类型的变量,而不需要区分数字字符串

可以使用%+v,%#v打印更详细的内容

2.2.17Json处理

image-20220514002110096

image.png go语言里面的JSON操作非常简单,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串。 序列化之后的字符串也能够JSON.unmarshaler去反序列化到一个空的变量里面。 这样默认序列化出来的字符串的话,它的风格是大写字母开头,而不是下划线。我们可以在后面用json tag等语法来去修改输出JSON结 果里面的字段名。

2.2.18时间处理

image.png

2.2.19数字解析

strconv包——string convert

使用parseInt,parseFloat解析字符串

Atoi把一个十进制字符串转成数字,可以用itoA把数字转成字符串

image.png

2.2.20进程信息

image.png

课后作业

  1. 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现
var guess int
_, err := fmt.Scanf("%d", &guess)
  1. 修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持

可以使用火山翻译,百度和网易尝试失败,只能固定单词求解
curlconverter.com/#go  将copy的cURL进行go语言代码的解析
oktools.net/json2go 将返回的payload的值,生成golang的结构体

  1. 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度
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语言介绍视频