目录
一、学习资料集锦
二、最佳实践
三、Go语言调试工具 - dlv使用
四、Go依赖管理
五、Go包管理工具
六、语法
Effective Go - The Go Programming LanguageGo is an open source programming language that makes it easy to build simple, reliable, and efficient software.http://docscn.studygolang.com/doc/effective_go.html
Query | GORM - The fantastic ORM library for Golang, aims to be developer friendly.Retrieving a single objectGORM provides First, Take, Last methods to retrieve a single object from the database, it adds LIMIT 1 condition when querying the database, and it will return the error ErrRhttps://gorm.io/docs/query.html
前言 · Go语言圣经https://books.studygolang.com/gopl-zh/index.html
go在线执行:https://play.golang.org/https://play.golang.org/
- channel:如何优雅地关闭Go channel - 简书
- mutex & channel:https://github.com/golang/go/wiki/MutexOrChannel
- empty struct: The empty struct | Dave Cheney
- profiling:使用 pprof 和火焰图调试 golang 应用 | Cizixs Write Here
- gc optimization:http://www.akshaydeo.com/blog/2017/12/23/How-did-I-improve-latency-by-700-percent-using-syncPool
GO语言调试利器——dlv - 简书安装后直接运行dlv将会看到如下信息: 上面列举了dlv的一些命令,其中常用的有如help、attach、core、debug、trace、version等。 dlv hel...https://www.jianshu.com/p/7373042bba83
dlv默认会一直在主协程上执行
1、项目改造:
source ~/.bash_profile 中添加dlv包的环境变量
1、改造build.sh脚本后&&编译sh build.sh
+ #go build -o bin/dape-wards
+ go build -gcflags="-N -l" -o bin/dape-dps main.go #必须这样编译,才能用gdb打印出变量,第二个是小写的L,不是大写的i注解:
-gcflags:给go编译传入参数 传给go tool compile的参数,因此可以用go tool compile --help查看所有可用的参数
-gcflags="-N -l" : -N:禁止优化 -I禁止内联
-ldflags:给go链接器传入参数 是给go tool link的参数,可以用go tool link --help查看可用的参数
2、调试
dlv exec bin/dape-wards
3、设置断点
b expand_create_activity.go:79
4、执行
c
5、发请求
curl "127.0.0.1:10183/unitysched/grindstoneCalc?cmd=unity_1_3_7_0"
6、查看变量
p len(schedAbleSps)
7、单步
n
8、进入函数
s
9、查看调用栈
bt
10、退出
quit
11、其他
h clearall : 清除所有断点
bp:查看所有断点
清除单个断点:h clear , clear 1
- go mod tidy : 下载包
- go fmt . :当前目录下格式化
- go fmt ./... :以当前目录递归格式化所有文件
- go get -u -t ./... : go mod依赖管理,更新依赖包最新版本到go.mod中 ; 详细使用:三分钟掌握Go mod常用与高级操作 - 知乎
- glide install
- glide cc && rm -rf vendor
- go1.9.1更新最新依赖包:glide cc && glide up && glide install
1、gomod和glide的区别
golang 1.11版本引入了包管理工具(go mod)不需要刻意设置gopath环境变量,默认$HOME/go目录作为gopath;之前都是靠vendor和GOPATH来管理依赖库的
2、gomod
export GOSUMDB=off
export GO111MODULE=auto
- off: GOPATH mode,查找vendor和GOPATH目录
- on:module-aware mode,使用 go module,忽略GOPATH目录
- auto:如果当前目录不在$GOPATH 并且 当前目录(或者父目录)下有go.mod文件,则使用 GO111MODULE, 否则仍旧使用 GOPATH mode
3、go clean --modcache:清除mod缓存
gcache工具
- go-cache 是一个基于内存的、高速的,存储k-v格式的缓存工具。
- 它适用于运行在单台机器上的应用程序,可以存储任何数据类型的值,并可以被多个goroutine安全地使用。
- 虽然go-cache 不打算用作持久数据存储,但是可以将整个缓存数据保存到文件(或任何io.Reader/Writer)中,并且能快速从中指定数据源加载,快速恢复状态
1、下载二进制包:All releases - The Go Programming Language
Mac OS 的Go语言开发包是 .pkg 格式的,安装包会默认安装在 /usr/local 目录下。
2、设置GOROOT环境:export GOROOT=/usr/local/go
3、设置GOPATH 工作区目录环境:export GOPATH=/xx/xx
go是一种静态强类型、编译型、并发型、垃圾自动回收的编程语言;
- 动态类型语言:动态性语言是指在运行期间才去做数据类型检查的语言;例如:python
- 静态类型语言:它的数据类型在编译期间检查,也就是说在写程序时要声明所有变量的数据类型;例如:C/C++、C#、Java等
- 强类型语言和弱类型其判断的根本是是否会隐形进行语言类型转变。强类型原因在速度上可能略逊于弱类型语言,但是强类型定义语带来的严谨性又避免了不必要的错误;
- Go 语言是一种强类型语言,而且没有隐式转换。也就是说运算符左右的变量类型必须一致
主要管理go协程切换和运行;
G-M-P模型
G代表Goroutine即协程
M表示Machine即工作线程
P表示Processor即处理器
协程、线程、进程
- 进程 是程序一次动态执行的过程,是程序运行的基本单位,每个进程都有自己的独立内存空间。
- 线程 是 CPU 调度的基本单位,多个线程可以通过共享进程的资源,通过共享内存等方式来进行线程间通信。
- 协程 可理解为轻量级线程,与线程相比,协程不受操作系统系统调度,协程调度由用户应用程序提供,协程调度器按照调度策略把协程调度到线程中运行。
变量声明
1、 指定变量类型,没有初始化,默认变量为零值;var v_name v_type
例如:var name string
2、声明一个变量并初始化(根据值自行判定变量类型)。例如:var name = "wwr"
3、var name = "wwr" 简写为 name := "wwr"
1、不会被修改,例如:const name = "wwr"
2、特殊的常量 itoa ,可以被修改
const(
a = itoa
b
c
) //第一个为0,后续的自动加1
1、for 循环
for i:= 0, i<10, i ++ {}
2、range 格式可以对 slice、map、数组、字符串等进行迭代循环
for key, value := range oldmap {}
3、While 语句形式
for sum <= 10{
sum += sum
}4、死循环
for {}
gorm框架
用于连接数据库
Query | GORM - The fantastic ORM library for Golang, aims to be developer friendly.Retrieving a single objectGORM provides First, Take, Last methods to retrieve a single object from the database, it adds LIMIT 1 condition when querying the database, and it will return the error ErrRhttps://gorm.io/docs/query.html
waitgroup
线程同步;主线程调用Add()函数来设置等待线程的数量,然后每个线程运行,并在完成后调用Done函数。Wait用来阻塞等线程执行结束后,主线程才会向下执行
Golang中WaitGroup使用的一点坑 - tianlongtc - 博客园Golang中WaitGroup使用的一点坑 Golang 中的 WaitGroup 一直是同步 goroutine 的推荐实践。自己用了两年多也没遇到过什么问题。直到一天午睡后,同事扔过来一段奇怪的https://www.cnblogs.com/tianlongtc/articles/8849952.html
func main() {
wg := &sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(wg *sync.WaitGroup, i int) {
log.Printf("i:%d", i)
wg.Done()
}(wg, i)
}
wg.Wait()
log.Println("exit")
}
interface用法介绍
理解Golang中的interface和interface{} - maji233 - 博客园在面向对象编程中,可以这么说:“接口定义了对象的行为”, 那么具体的实现行为就取决于对象了。 在Go中,接口是一组方法签名(声明的是一组方法的集合)。当一个类型为接口中的所有方法提供定义时,https://www.cnblogs.com/maji233/p/11178413.html
接口定义了对象的行为
接口是一组方法签名(声明的是一组方法的集合)。当一个类型为接口中的所有方法提供定义时,它被称为实现该接口
type a interface {
GetA() string
GetB() int
}
type c interface {
GetC() int
}
type b struct {}
func (s b) GetA() string {
return ""
}
func (s b) GetB() int {
return 0
}
func (s b) GetC() int {
return 0
}
a是一个接口,定义了geta、getb方法
b类实现了geta、getb
c是一个接口,定义了getc方法
b类实现了getc
—— 依赖参数是a,传入参数是b
—— 依赖参数是c,传入参数是b
生下来就是指针类型
chan:一个阻塞队列
map
slice
函数func
interface:一个类型为interface{}或者interface接口的变量可能是指针变量,也可能是普通变量
两大操作符
&(取地址符):返回该变量的内存地址
*(取值符):返回该指针指向的变量的值,可以进行修改指针指向内存地址的值
nil:空指针
用法1:
result := &tehui_common.PassengerResult{} —— 返回初始化结构体对象的地址
sc.ContextMap.Store(common.TehuiPassengerResult, result) —— 存放的是地址
data, ok := sc.ContextMap.Load(common.TehuiPassengerResult) —— 取地址
var passengerResult *PassengerResult
if passengerResult, ok = data.(*PassengerResult); !ok { —— 取值
return nil, errors.Errorf("passenger result [%v] is not type *module_model.PassengerResult", data)
}用法2:
var result tehui_common.DriverResult —— 初始化一个结构体对象
sc.ContextMap.Store(common.TehuiDriverPrice, &result) —— 存放地址
data, ok := sc.ContextMap.Load(common.TehuiDriverPrice) —— 取地址
var driverResult *DriverResult
if driverResult, ok = data.(*DriverResult); !ok { —— 取值
return nil, errors.Errorf("driver result [%v] is not type *DriverResult", data)
}