Golang相关学习记录
书签
练习代码 https://gobyexample.com/
电子书,过程很详细 https://books.studygolang.com/gopl-zh/ch1/ch1-03.html
第三方库整理 https://github.com/avelino/awesome-go
挺实用的教程 https://blog.csdn.net/erlib/article/details/50970761
mysql操作 https://github.com/go-sql-driver/mysql
标准库中文文档 https://studygolang.com/pkgdoc
笔记
类似下面类型在前的函数,表示声明的是Fahrenheit类型的一个名叫String的方法
func (f Fahrenheit) String() string{
return fmt.Sprintf("%g°F", f)
}
常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一。
下面是来自time包的例子,它首先定义了一个Weekday命名类型,然后为一周的每天定义了一个常量,从周日0开始。在其它编程语言中,这种类型一般被称为枚举类型。
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
结构体初始化
type Point struct{ X, Y int }
p := Point{1, 2}
创建结构体指针
pp := &Point{1, 2}
//它是下面的语句是等价的
pp := new(Point)
*pp = Point{1, 2}
函数值之间是不可比较的,也不能用函数值作为map的key
Deferred用法
只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当defer语句被执行时,跟在defer后面的函数会被延迟执行。直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。
defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。
package ioutil
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return ReadAll(f)
}
通过嵌入结构体扩展类型
var (
mu sync.Mutex // guards mapping
mapping = make(map[string]string)
)
func Lookup(key string) string {
mu.Lock()
v := mapping[key]
mu.Unlock()
return v
}
如果只是导入一个包而并不使用导入的包将会导致一个编译错误。但是有时候我们只是想利用导入包而产生的副作用:它会计算包级变量的初始化表达式和执行导入包的init初始化函数(§2.6.2)。这时候我们需要抑制“unused import”编译错误,我们可以用下划线_来重命名导入的包。
import _ "image/png" // register PNG decoder
如果我们想同时导入两个有着名字相同的包,例如math/rand包和crypto/rand包,那么导入声明必须至少为一个同名包指定一个新的包名以避免冲突。这叫做导入包的重命名。
import (
"crypto/rand"
mrand "math/rand" // alternative name mrand avoids conflict
)
基于反射的代码通常比正常的代码运行速度慢一到两个数量级。对于一个典型的项目,大部分函数的性能和程序的整体性能关系不大,所以使用反射可能会使程序更加清晰。测试是一个特别适合使用反射的场景,因为每个测试的数据集都很小。但是对于性能关键路径的函数,最好避免使用反射。
GRPC使用笔记
go get -u github.com/golang/protobuf/{proto,protoc-gen-go} //下载插件 需要将$GOPATH/bin添加到运行路径
go get -u google.golang.org/grpc //下载GRPC 没有也可以生成pb文件,但是程序没法用
- 参数:指定import路径,可以指定多个-I参数,编译时按顺序查找,不指定时默认查找当前目录
- –go_out -golang编译支持,支持以下参数
- plugins=plugin1+plugin2 - 指定插件,目前只支持grpc,即:plugins=grpc
- M 参数 - 指定导入的.proto文件路径编译后对应的golang包名(不指定本参数默认就是.proto文件中import语句的路径)
- import_prefix=xxx -为所有import路径添加前缀,主要用于编译子目录内的多个proto文件,这个参数按理说很有用,尤其适用替代一些情况时的M参数,但是实际使用时有个蛋疼的问题导致并不能达到我们预想的效果,自己尝试看看吧
- import_path=foo/bar - 用于指定未声明package或go_package的文件的包名,最右面的斜线前的字符会被忽略
- 末尾 :编译文件路径 .proto文件路径(支持通配符)
protoc -I . --go_out=plugins=grpc,Mfoo/bar.proto=bar,import_prefix=foo/,import_path=foo/bar:. ./*.proto
简单命令:protoc –go_out=plugins=grpc:. helloworld.proto