【后端青训营笔记】Go语言基础以及Go语言案例实战

95 阅读3分钟

0x0 Golang语法

Golang的语法看起来像C++和JavaScript和Python的融合体,学过其他语言上手Golang的话其实会觉得比较别扭。(比如经典的没有分号,for和if的expression没有括号) 这里提一些Golang特有的写法

指针也用.访问field

有C / C++经验的同学学习的时候可能会疑惑为什么指针类型不用取值后再用.访问结构体成员,因为Golang在编译的时候就自动转换好了,这样可以减少大家开发过程中的错误。(当然现代IDE的补全也不会让大家犯符号的错误)

// 参考下面的结构体
type foo struct {
    x, y int
}
var f1 *foo = &foo{}
var f2 foo = foo{}

// 两者都是通过f1.x, f1.y; f2.x, f2.y;去访问x, y
fmt.Println(f1.x) // 0
fmt.Println(f2.x) // 0
// 都输出0是因为开辟新内存都是0

条件语句赋值语法糖:

if val, ok := dict[x]; ok {
}

但需要注意的是,这样的语法糖val只能在if结构体内使用

同理的还有forexpression里赋值

makenew

这两者在Golang中存在很大的区别,有C++或者Java的经验的同学应该会更熟悉new但是在Golang中我们更常见make,这并不是说我们用make去malloc一切,而是我们不需要malloc,Golang在编译后会帮我们把声明赋值好的变量自动开辟内存,例如:

f1 := &foo{}
// 等价于
f3 := new(foo)

更多底层细节可以参考掘金的好文

Golang make和new的区别 - 掘金 (juejin.cn)

Go make 和 new 的区别 - 掘金 (juejin.cn)

slice切片扩容

在数组中我们有添加元素的需要通常会使用slice,但是其底层实现数组是定长的,因此Golang标准语法中就有了append,作为slice添加元素同时数组扩容的实现。

append(slice []Type, elems ...Type) []Type

使用append如果触发扩容,则会生成新的数组副本,因此在函数中传递切片的并在函数触发扩容的时候就要注意了坑了。如果是希望传参的切片是在函数内更新的话,请传切片地址作为参数,这样就能保证修改的都是原切片

关于append的坑,掘金里也有一篇好文帮大家试错了

Go切片append采坑经验分享 - 掘金 (juejin.cn)

goroutine

Golang的最大特点之一,协程,使用方式:

var dfs func = func (i, j int) {}
go dfs
go func() {}

只需要简单的go加func即可使用协程并发执行函数,多数情况下是需要各协程直接相互协作的,则引出下面特殊类型

channel 通道

学习过操作系统的同学对pipe都不陌生,在Golang中可以使用channel让进程通信

c := make(chan int) // new一个非缓冲channel(即会阻塞)
// 等价于
c := make(chan int, 0) // capacity为0
c := make(chan int, 10) // new一个缓冲区capacity为10的int通道
c <- 2 // 2写入
num := <- c // num读出

关于如何并发控制,掘金上有一篇好文章

深入理解Golang之channel - 掘金 (juejin.cn)

0x1 Golang常用标准库记录

Package Name用途
fmt标准输入输出
log日志库(但是比较简陋)
strings字符串操作
strconv字符串转换其他类型
bufio流读写
net网络库(Golang的优势之一)
sync同步库,操作系统级实现锁
atomic原子操作,硬件级实现锁
time时间库
math数学运算,随机数rand也在该库内
testing测试
更多库及方法示例待更新 To be continue...