数据类型

array

  1. 初始化, b := [2]string{"Penn", "Teller"}
  2. 初始化,编译器计算自动计算长度 b := [...]string{"Penn", "Teller"}
  3. 数组的赋值是直接拷贝整个数组,变量赋值本质上是一次内存浅拷贝,切片的赋值是拷贝了切片头,字符串的赋值是拷贝了字符串的头部,接口变量的赋值同样是浅拷贝

string

Strings, bytes, runes and characters in Go

等价于一个只读的字节Slice

len 方法返回的时候字节数,非字符数

rune

int32 4个字节 单括号字面量

关键字

switch

  • 不需要break语句
  • 支持表达式

容器

Slice - 切片

Go Slices: usage and internals

  1. 初始化, letters := []string{"a", "b", "c", "d"}
  2. make初始化, s := make([]byte, 5(leg), 5(cap,可选,不填写默认与长度相同))
  • 与Java不同,扩容后返回新Slicce,一定要接收返回值
  • nil slice 支持append
  • s[x:y] 共享底层数据,小Slice引用大Slice,可能会早成无法被垃圾回收,使用复制去处对大Slice的引用

Map

  1. 初始化 n := map[string]int{"foo": 1, "bar": 2}
  2. make初始化 m := make(map[string]int)
  3. v1 := m["k1"]
  4. v2, ok := m["k2"] ok 判断是否存在,主要用于区分零值

range -迭代器

  1. 数组 or 切片 for i, num := range nums
  2. 字典 for k, v := range kvs for k := range kvs
  3. 字符串 for offset, runeValue := range "go"

Struct

参数传递

Go 语言支持值传递,也支持指针传递。值传递涉及到结构体字段的浅拷贝,指针传递会共享结构体内容,只会拷贝指针地址

匿名内嵌结构体

会继承方法,实际上是语法糖,基于组合实现继承

标签

字段元数据标注,作用类似于Java注解,可用于标记json字段名等

Interfaces

鸭子类型,不需要显示继承,

可以实现面向对象中的多态,interface{} 等价于 Java里的Object

异常处理

Error

相对繁琐,但官方推荐

Panic

相对简洁,类似于Java 的 throw try catch

defer

相当于Java的finally,用于关闭流、释放资源或锁,最先 defer 的语句最后执行

Goroutine - 协程 - 轻量级线程

1
go func("xxx")

Channel - 通道

1
2
3
4
5
6
7
8
9
// 缓冲型通道,里面只能放整数
// 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

包管理

1
2
3
4
5
6
//名称替换 支持同名包
import pmathy "github.com/pyloque/mathy"
import omathy "github.com/other/mathy"

// 类似于Java中的static import
import . "github.com/pyloque/mathy"

参考

1、快学 Go 语言 by 老钱

2、Go by Example