导图社区 Go语言导图笔记
Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。下图梳理了Go语言基础的基础语法、语言基础特性、面向过程的特性、面向对象的特征、自有特性。
编辑于2021-06-30 10:29:21Go语言基础
基础语法
标记
程序的基本元素
组成
关键字
标示符
常量
字符串
符号
行分隔符
;
自然行中只有一行代码时可以省略
Go语言鼓励使用自然行分隔代码行,尽量不使用行分隔符
注释
单行注释
// 这是单行注释
多行注释
/* 我是多行注释 */
命名
推荐驼峰命名
标示符
用来命名变量、类型等程序实体
不可以
数字开头
关键字
运算符
字符串连接
可以通过 + 实现
关键字
25个常用关键字
36个保留关键字
空格
语句中适当使用空格能让程序更易阅读
语言基础特性
数据类型
布尔型
常量 true 或者 false
数字类型
整数类型
int
int8
int16
int32
int64
uint
uint8
uint16
int32
int64
uintptr
用于存放指针的无符号整型
浮点数类型
float32
float64
IEEE-754标准的浮点型数
complex64
32 位
complex128
64 位
实数和虚数
其他数字类型
byte
类似 uint8
rune
类似 int32
字符串类型
一串固定长度的字符连接起来的字符序列
Go语言,使用 UTF-8 编码标识 Unicode 文本
错误类型
error
复合类型
指针类型
数组类型
枚举类型
结构体类型
Channel 类型
函数类型
切片类型
接口类型
Map 类型
变量
变量声明
使用关键字var或者:=
3种方式
1.指定类型,不初始化
var 变量名 变量类型
2.不指定类型,指定初始值,自动判断类型
类型推导
var 变量名 = 数据值
3.为第二种的简写形式,不能在全局中使用
短变量声明
变量名 := 数据值
多变量声明
多个相同类型的变量,用逗号(,)连接
var a1,a2,a3
多个不同类型,用var 语句块
var { v1 int v2 string}
匿名变量
用下划线_表示
接收函数的返回值时,忽略某个返回值
值类型和引用类型
常量
常量的定义格式
单个声明
const identifier [type] = value
批量声明
const { identifier1 [type1]=value1 identifier2 [type2]=value2 }
数据类型
布尔
数字
字符串
分类
显式类型定义
指定数据类型
隐式类型定义
不指定数据类型
多个相同类型定义
多个相同类型的常量,用逗号(,)连接
特殊常量
iota
常量计数器,只能在常量的表达式中使用
作用
可以被用作枚举值
运算符
语句
条件语句
if else
switch
不同条件执行不同动作,从上至下逐一测试,直到匹配为止
默认情况下 case 最后自带 break 语句
若需要执行后面的 case,可以使用 fallthrough
select
与switch的区别
随机执行一个case子句
适用
用于处理异步IO操作
如果有多个case都可以运行,select会随机公平地选出一个执行,其他不会执行
如果没有可运行的case语句,且有default语句,那么就会执行default的动作
如果没有可运行的case语句,且没有default语句,select将阻塞,直到某个case通信可以运行
不支持三目运算
循环语句
for
for init; condition; post { }
变量表达式条件循环
for condition { }
真值条件循环
for { }
无限循环
break
continue
跳转语句
goto
面向过程的特性
函数
程序的入口main函数
函数的定义
func function_name([parameter list]) [return_types] { 函数体}
函数的调用
return_value = function_name()
函数的参数
参数简写
多个相同类型的参数,可以省略类型
例如:func funcName(x, y int){}
不定参数
不定数量的不定参数
func function_name(param ...paramType) { 函数体}
任意类型的不定参数
func function_name(param ...interface{}) { 函数体}
在函数之间,不定参数的传递
func myfunc(args ...int) { // 按原样传递 myfunc3(args...) // 传递片段,实际上任意的int slice都可以传进去 myfunc3(args[1:]...)}
传递方式
值传递
引用传递
函数返回值
Go支持多个返回值
func function_name( [parameter list] ) ([return_types]){ 函数体}
return_value1, return_value2 := function_name()
支持匿名返回值
使用下划线表示
return_value, _ := function_name()
Go语言函数没有重载
函数名不可重名
函数类型
函数类型的变量
函数本身也是一种类型,它包含了函数的参数和返回值
函数类型可以作为变量,进行赋值
函数作为另一个函数的参数
函数作为另一个函数的返回值
匿名函数与闭包
匿名函数由一个不带函数名的函数声明和函数体组成
直接赋值给变量
直接执行
闭包是可以包含自由变量的代码块
变量的作用域
局部变量
函数体内定义的变量
全局变量
函数外定义的变量
形式参数
函数定义中的变量
数组
定义
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列
数据类型可以是任意的原始类型例如整形、字符串或者自定义类型
声明
var variable_name [SIZE] variable_type
和切片类似只是指定容量大小
实例
var balance [10] float32
初始化
var balance = [5]int32{1,2,3,4,5}
var balance = [...]int32{1,2,3,4,5}
访问数组元素
其它
多维数组
数组参数
指针
定义
通常所说的指针是指针变量
指针变量是存放了内存地址的一类特色变量
指针相关的操作符
*
指针变量修饰符
指针声明时
取指针值操作符
指针运算时
&
取地址操作符
根据变量名取指针变量值
声明
var point_name *type
实例
var ip *int /* 指向整型*/var fp *float32 /* 指向浮点型 */
初始化
结构体
定义
声明
type struct_variable_type struct { member definition member definition ... member definition}
初始化
make
new
访问结构体成员
作为函数参数
作为指针
结构体嵌套
特性
1. 可以直接访问其成员变量
2. 字段名是其的类型名
初始化
命名
作用
可以模拟类的继承
面向对象的特性
类型系统
为类型添加方法
func type_name function_name([parameter list]) [return_types] { 方法体}
可见性
没有访问修饰符,像public、private
表示变量公有访问的大写
表示变量私有访问的小写
接口
定义
把所有的具有共性的方法定义在一起的数据类型
声明
语法
type interface_name interface { method_name1 [return_type] method_name2 [return_type] method_name3 [return_type] ... method_namen [return_type]}
例子
Any类型
继承
语法上不支持,可以通过组合实现
错误处理
Go错误处理思想设计
将错误处理视为正常开发必须实现的环节
不主张由异常处理机制错误,而是由开发者自行处理
使用返回值返回错误的机制,可以降低编译器、运行时处理错误的复杂度
错误处理特征
1.有可能造成错误的函数,必须返回一个错误,若是成功,返回 nil
2.函数调用必须检查错误,如果发生错误,则进行必要的错误处理
error 接口
相当于Exception
errors.New
自定义错误
defer语句
作用
用于延迟执行一个函数或者语句
错误处理中,相当于finally
执行规则
多个defer语句,按FILO(先进后出)规则执行
return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步
defer语句执行的时机就在返回值赋值操作后,RET指令执行前。
defer执行时机
内置函数
panic
相当于throw
recover
相当于catch
自有特性
切片(Slice)
定义
切片是对数组的抽象,是一种动态的数组
声明
var identifier []type
和数组类似只是没有指定容量大小
实例
var numbers = make([]int,3)
var numbers = make([]int,3,5)
初始化
numbers := []int{1,2,3}
空切片(nil)
只声明了而未初始化的切片,就是空切片
空切片值为nil,长度为0
切片截取
slice_name[lower-bound:upper-bound]
切片名(下限:上限)
上下限确定的是切片的前闭后开区间,即:[下限,上限)
基础函数
len()
长度
cap()
容量
append()
追加
copy()
复制
make([]type, len,[capacity])
范围(range)
用于for循环中遍历,元素的索引及对应的值
作用对象
数组(array)
切片(slice)
nums := []int{2, 3, 4}sum := 0for i, num := range nums { sum += num}
通道(channel)
集合(map)
集合(map)
定义
一种无序hash实现的键值对的集合
对应与Java里的HashMap
声明及初始化
声明语法
var map_name map[key_data_type]value_data_type
例子
初始化语法
map_name := make(map[key_data_type]value_data_type)
map_name := map[key_data_type]value_data_type{ key:value, key:value,}
例子
基础操作
插入
map_name[key] = value
取值
key_value := map_name[key]
删除
delete(map_name, key)
并发处理
goroutine
通道(channel)
定义
是一种类似队列的数据类型,用于goroutine 间数据通信
声明及初始化
声明语法
var 通道变量 chan 通道类型
例子
var ch1 chan int
初始化语法
通道实例 := make(chan 元素类型)
通道实例 := make(chan 元素类型, [缓冲大小])
例子
ch1 := make(chan int)
操作
声明(定义)
ch := make(chan int)
发送
ch <- 10
把10发送到ch中
接收
x := <- ch
从ch中接收值并赋值给变量x
<-ch
从ch中接收值,忽略返回结果
关闭
close(ch)
分类
按流向分类
单向通道
只读通道
var 通道变量 <-chan 通道类型
var ch1 <-chan int
只写通道
var 通道变量 chan<- 通道类型
var ch1 chan<- int
双向通道
默认的
按接收数据的方式分类
阻塞接收
非阻塞接收
阻塞接收任意数据
循环接收
按缓冲分类
无缓冲通道
有缓冲通道
缓冲机制
即声明一个带有缓冲区的通道
c := make(chan int, 1024)
超时机制
又叫阻塞机制,当通道阻塞的时候,超过设定的时间,就会panic
select多路复用
于多路监昕多个通道
执行方式
若是有多个通道可以读写,则随机选择一个执行
若是有只有一个通道可以读写,则执行这一个
若是没有可以执行的通道,则阻塞,直到有可执行的通道为止
多核并行化
runtime.GOMAXPROCS
设置最多使用几个CPU核心
NumCPU
获取OS的核心数
并发安全和锁
起因
为了让多个协程之间,可以安全的共享和操纵数据
解决竞态问题
类型
互斥锁
sync.Mutex
读写互斥锁
sync.RWMutex
等待锁定的任务完成
sync.WaitGroup
全局唯一性操作
sync.Once
并发集合
sync.Map
Load
Store
LoadOrStore
Delete
非并发安全的Map,并发修改时
error:concurrent map writes
原子操纵
sync.atomic
Load
Store
Add
CompareAndSwap
临时变量池
sync.Pool
类似于ThreadLocal
目的
为可重用的临时对象提供存放的地方,以减少以减轻GC的压力
让创建高效而线程安全的空闲列表,变得更容易
适用场景
适合存放寿命较长的临时对象
Get
Put