前言
TIDB K8S 由GO 语言编写;mysql 和 mongodb 由c++编写
go 没有构造和析构,没有运算符重载,没有形参默认值,没有继承,没有泛型
go 原生支持 Unicode,可以处理所有国家的语言
{ 符号必须和关键字 func 在同一行
gofmt 保存的时候自动格式化go代码
goimports 保存的时候自动导入包
gometalinter 保存的时候自动检查go 语法
for 循环的三种形式:
for 初始化条件;条件(布尔值);循环体之后被执行的表达式 {
}
for 条件(布尔值){
// 传统的while 循环
}
for _,arg := range os.Args[1:]{
}
Printf 各种参数解释:
%d 十进制 %x 十六进制 %o 八进制 %b 二进制 %f/%g 浮点数 %t 布尔型
%c 字符(unicode码点) %s 字符串 %q 带引号字符串 %v 内置格式任何值
%T 任何值的类型 %% 百分号本身
声明的作用域是在程序文本中出现的区域,是一个编译属性
变量的生命周期是变量在程序执行时被程序其它部分所引用的起止时间,是一个运行属性。匿名函数就是生命周期大于作用域的是例子
基本数据类型
四大类:基础类型;聚合类型(数组和结构体,slice,map);引用类型(指针,slice,map,函数,channel);接口类型
rune = int32 byte = uint8 uintptr 无符号整数,大小不明确,用于存放指针
字符串是不可变的字节序列,不能修改
常量是一种表达式,必须在编译阶段就能计算出值
常量生成器iota 从0开始逐步加1
数组的定义方式 var a [3]int = [3]int{1,2,3} q := […]int{1,2,3}
[3]int 和 [4]int 并不是同一个类型
slice 通常写成 []T ,看上去像是没有长度的数组类型
map是go语言中散列表的引用。 ages := make(map[string]int)
函数
func name(parameter-list) (result-list){
body
}
方法
方法的声明和普通函数的声明类似,只是函数名字前面多了一个参数,将方法绑在参数对应的类型上
func (p Point) name(parameter-list) (result-list){
// 将方法绑在Point类型上
}
go 语言中没有this 和 self
go 和许多其他面向对象语言不同,它可以将方法绑定在任何类型上
同一个包下的任何类型都可以声明方法,只要它的类型既不是指针类型也不是接口类型
由于主调函数会复制每一个实参变量,如果一个函数需要更新一个变量,或者一个实参太大,我们想避免复制整个实参,因此需要使用使用指针传递变量的地址
指针接收着合法的三种情况:
形参接收者和实参接收者是同一类型。比如都是T类型或T类型;
实参接收者是T类型,形参接收者是T类型。编译器或隐式获取变量的地址;
实参接收者是*T类型,形参接受者是T类型。编译器隐式解引用接收者,获取实际的值
接口
接口中只包含0个或多个方法签名,不包含具体实现
实现接口不需要显示声明,只需要实现相应方法即可
type Namer interface {
method1(param_list) return_list
}
接口的名字最好是以 er , r , able 结尾
空接口是指没有定义任何方法的接口。空接口类型的变量可以存储任意类型的变量
类型的断言 x.(T) x 表示类型为interface{}的变量
T 表示断言x可能是的类型 true表示断言成功 false 表示断言失败
协程和通道
通常一个进程里启动上万个线程,系统就不堪重负。go 可以轻松开启百万协程
通道是并发安全的数据结构,类似于内存消息队列,允许很多协程并发对通道进行读写
main函数运行在主协程里。go 语言里只有一个主协程,其余都是子协程,子协程是平行关系
主协程运行结束,其它协程就会立即消亡,不管它们是否已经开始运行
子协程异常退出会传播到主协程,导致主协程也会挂掉
var chan1 chan string
chan2 = make(chan string)
单向channel var chan3 chan <- int chan3 := make(chan <- int)
for range 可以读取 chan 中的值
操作值为nil的channel ||| 被关闭的channel ||| 正常的 channel
close : panic panic 成功关闭
c<- : 永远阻塞 panic 阻塞或成功发送
<-c :永远阻塞 永远不阻塞 阻塞或成功接收
错误和异常
fmt.Errorf 和 errors.New("something happened ") 自定义一个错误
panic 和 recover 处理异常,然后升级为错误返回给系统
使用共享变量实现并发(即传统的同步机制)
type a struct {
a int
lock sync.Mutex
}
每个OS线程有一个固定大小的栈内存,一般为2MB左右
协程的栈不是固定大小的,典型情况下为2kb ,最大限制达到1GB
OS线程由OS内核调度,每隔几毫秒,一个硬件中断发给CPU,CPU调用一个调度器的函数,这个函数暂停正在运行的线程,将寄存器信息保存在内存
go 协程有自己的调度器,于内核调度器类似,但不是由硬件时钟触发,而是go 语言内部结构触发,不需要切换至内核环境
GOMAXPROCS 是m:n 模型中的n
休眠和正在被通道阻塞的gorutine不占用线程
阻塞在I/O 和 其它系统中或调用非go写的函数,gorutine需要一个单独的os线程,但这个线程不计算在GOMAXPROCS中
普通线程有独特的标识;gorutine 没有标识
包 和 go工具
go 自带100多个包 go社区的包可以在http://godoc.org中找到
go 编译比其它语言快,主要有三个原因
所有的导入都必须在每一个源文件的开头显示列出;
包的依赖性形成有向无环图,因为没有环,所以包可以独立编译;
包编译输出的目标文件不仅记录自己的导出信息,还记录所依赖包的导出信息。编译包时,编译器必须从每一个导入读取目标文件,但不会超过这些文件
import (
"fmt"
"os"
)
import (
crypto/rand
mrand ***/rand //避免冲突
)
import (
_ "img" //空导入
)
import (
"geometry/rectangle"
)
var _ = rectangle.Area // 错误屏蔽器
func main() {
}
import (
_ "geometry/rectangle" //调用了rectangle 包的Init函数,不需要在代码中使用
)
func main() {
}
包名一般使用简短的名字
go env 查看环境配置
大部分用户必须进行的唯一的配置是 GOPATH环境变量
GOROOT:GO发行版的根目录,用户无需设置GOROOT
go get -u 获取每个包的最新版本
go build / go build . : 意味着对当前目录进行编译
GOARCH 处理器的架构 GOOS 目标操作系统
go build 的作用:
用于测试编译多个包或一个main包;
build 命令编译包丢弃非main包编译结果,只是检查是否能够被编译;
保留main包的编译结果;
/bin 存放编译后的可执行文件 /pkg 存放编译后的包文件
package main
import (
"fmt"
"cal" //到入自定义的包,cal必须在src文件下,必须和main同一级
)
func main() {
fmt.Println("hello word")
fmt.Println("相加",cal.Add(10,20))
fmt.Println("相减",cal.Subtraction(40,50))
}
普通包【非main包】
go build add.go 【编译add.go,不生成exe执行文件】
go build -o add.exe add.go 【指定生成exe执行文件,但不能运行此文件,不是main包】
main包
go build main.go 【生成exe执行文件】
go build -o main.exe main.go 【指定生成main.exe可执行文件】
如果是main包,当你执行go build 之后,会在当前目录生成一个可执行文件.exe。
如果需要再$GOPATH/bin下生成相应的文件,需要执行go install 或 go build -o 路径/ XXX.exe XXX.go
项目文件夹下有多个文件
go build 【编译当前目录下所有的go 文件】
go build add.go delete.go 【编译add.go 和 delete.go】
go build 会忽略目录下以 _ 或 . 开头的文件
go test
文件名以 _test.go 结尾
test 测试的方法名以 Test 打头,形参为(t * testing.T),检查程序的逻辑是否正确
benchmark(基准)测试以 Benchmark 打头,形参为(t * testing.T),衡量函数的性能
example测试的方法以 Example 打头,形参为(t * testing.T ),提供一个由编译器保证正确的文档
go test -v hello_test.go 测试整个文件
go test -v hello_test.go -test.run TestHello 测试单个函数
go run
用于对命令源码文件做编译+链接操作 操作产生临时可执行程序并执行,一般用于调试程序
go install
用于 构建 + 安装包
对 库源码文件 go install ,直接编译整个包,会个pkg目录下生成.a静态文件,供其他包调用
对 命令源码文件 go install ,编译+链接+生产可执行文件,会在/bin目录下生成可执行文件
go build 和 go run 后面加**.go文件 go install 后面直接加xxx目录名