Go Learn
数据类型
array
- 初始化,
b := [2]string{"Penn", "Teller"}
- 初始化,编译器计算自动计算长度
b := [...]string{"Penn", "Teller"}
- 数组的赋值是直接拷贝整个数组,变量赋值本质上是一次内存浅拷贝,切片的赋值是拷贝了切片头,字符串的赋值是拷贝了字符串的头部,接口变量的赋值同样是浅拷贝
string
Strings, bytes, runes and characters in Go
等价于一个只读的字节Slice
len 方法返回的时候字节数,非字符数
rune
int32 4个字节 单括号字面量
关键字
switch
- 不需要break语句
- 支持表达式
容器
Slice - 切片
Go Slices: usage and internals
- 初始化,
letters := []string{"a", "b", "c", "d"}
- make初始化,
s := make([]byte, 5(leg), 5(cap,可选,不填写默认与长度相同))
- 与Java不同,扩容后返回新Slicce,一定要接收返回值
- nil slice 支持append
- s[x:y] 共享底层数据,小Slice引用大Slice,可能会早成无法被垃圾回收,使用复制去处对大Slice的引用
Map
- 初始化
n := map[string]int{"foo": 1, "bar": 2}
- make初始化
m := make(map[string]int)
v1 := m["k1"]
v2, ok := m["k2"]
ok 判断是否存在,主要用于区分零值
range -迭代器
- 数组 or 切片
for i, num := range nums
- 字典
for k, v := range kvs
for k := range kvs
- 字符串
for offset, runeValue := range "go"
Struct
参数传递
Go 语言支持值传递,也支持指针传递。值传递涉及到结构体字段的浅拷贝,指针传递会共享结构体内容,只会拷贝指针地址
匿名内嵌结构体
会继承方法,实际上是语法糖,基于组合实现继承
标签
字段元数据标注,作用类似于Java注解,可用于标记json字段名等
Interfaces
鸭子类型,不需要显示继承,
可以实现面向对象中的多态,interface{} 等价于 Java里的Object
异常处理
Error
相对繁琐,但官方推荐
Panic
相对简洁,类似于Java 的 throw try catch
defer
相当于Java的finally,用于关闭流、释放资源或锁,最先 defer 的语句最后执行
Goroutine - 协程 - 轻量级线程
go func("xxx")
Channel - 通道
// 缓冲型通道,里面只能放整数
// java.util. concurrent .ArrayBlockingQueue
var bufferedChannel = make(chanint, 1024)
// 非缓冲型通道 必须确保有协程正尝试读取,否则写操作会阻塞直到有其它协程来从通道中读
// java.util.concurrent.SynchronousQueue
var unbufferedChannel = make(chanint)
// 箭头语法糖 <-
channel <- x // 写通道
x <- channel // 读通道
读写阻塞
通道满,写协程阻塞,直至有协程读取,唤醒一个写阻塞协程
通道空,读协程阻塞,直至有协程写入,唤醒一个读阻塞协程
关闭通道
确保通道写安全的最好方式是由负责写通道的协程自己来关闭通道,通道关闭后读协程还可以读未读区的数据
支持for range 语法,空通道循环暂停并阻塞当前协程,通道关闭阻塞停止且循环结束
Select 多通道
通道「多路复用」语法糖,同时管理多个通道读写,所有通道都不能读写就整体阻塞,只要有一个通道可以读写就会继续
select语句default可以决定通道读写操作是否阻塞
内部结构
循环数组通过读写偏移量来控制元素发送和接受。一个全局锁来控制并发并保证线程安全。两个队列分别保存阻塞的发送和接收协程
与Java 语言内置的 ArrayBlockingQueue 结构如出一辙。队列在本质上是使用共享变量加锁的方式来实现的,共享变量才是并行交流的本质
所以读者请不要认为 Go 语言的通道很神奇,Go 语言只是对通道设计了一套便于使用的语法糖,让这套数据结构显的平易近人。它在内部实现上和其它语言的并发队列大同小异
并发工具
WaitGroup
类似于CountDownLatch
包管理
//名称替换 支持同名包
import pmathy "github.com/pyloque/mathy"
import omathy "github.com/other/mathy"
// 类似于Java中的static import
import . "github.com/pyloque/mathy"