- Golang的int/uint类型占多少位?
- Go GRPC
- 文件目录
- helloword.proto依赖common.proto
- 编译, 若切换到proto目录, 应该指定—proto_path为上层目录,才能import comm/common.proto
- 但是执行后会报错
- ./helloworld.proto: File does not reside within any path specified using —proto_path (or -I). You must specify a —proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names — protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it’s harder than you think).
- 这是因为当—proto_path指定路径后, 后面的待编译文件./helloworld.proto的搜索路径也会
- 变成在—proto_path下的路径搜索, 而../这个目录即grpc_demo, 下面不包含./helloworld.proto
- 所以报错找不到helloworld.proto
- 可以改成如下两种方式
- 如下,指定了-i会清除安装的包,由于加上了-n,只会输出命令,并不执行
- 查看google.golang.org/protobuf@v1.26.0依赖哪些模块
- 查看google.golang.org/protobuf@v1.26.0被哪些模块依赖
Golang的int/uint类型占多少位?
- golang中整数类型包括int8/int16/int32/int64,分别指明了占用的内存大小
- 而默认的int/uint类型,具体内存大小由机器的cpu位数决定,如果是32位,则int为32位,若cpu为64位,则int为64位,现在大多数机器cpu是64位,所以int为64位,这一点和其他语言可能不一样
- 可以使用
strconv.IntSize
来获取该机器中int占用的位数大小 ```go //strconv.IntSize中使用如下方法来判断int是32位还是64位 const host32bit = ^uint(0)>>32 == 0
//一点小知识 x := ^uint32(0) // x is 0xffffffff i := int(x) // i is -1 on 32-bit systems, 0xffffffff on 64-bit fmt.Println(i)
<a name="ukh8P"></a>
### MySQL中的int(M)
- MySQL建表时,对于整数字段,有如下几类
- tinyint:占一个字节
- smallint:占两个字节
- mediumint:占三个字节
- int/integer:占四个字节,这两个类型都是同一个,只是写法区别
- bigint:占八个字节
- 对于整数类型,通常建表时,我们会在后面加上(M),这个叫做显示宽度,与字段的存储长度无关,存储长度仍然由前面的类型决定;当存储的数值位数小于M时,显示时会补0,超过则不会,且只有对字段指定了`zerofill`才会生效。
- 如下,可以看到123由于不够5位,会补0。注意显示宽度只会影响数据查看显示而已,不会影响存储,且需要对字段制定了`zerofill`才会生效
- 另外吐槽下goland自带的mysql client这个显示宽度不生效,直接是默认int(10)
```sql
mysql> create table zerofill_test (
id int primary key,
user_id int(5) zerofill
)ENGINE=innodb, CHARSET=utf8
mysql> insert into zerofill_test value (1, 123)
mysql> insert into zerofill_test value (1, 12356)
mysql> select * from zerofill_test;
+----+---------+
| id | user_id |
+----+---------+
| 1 | 00123 |
| 2 | 123456 |
+----+---------+
Go GRPC
- grpc是一个通用的rpc框架,通过语言无关的proto文件来定义通信接口协议,并且使用protoc(工具包)根据proto文件生成指定语言的pb文件
- 注意几个概念
- grpc:一种通用的grpc协议(google rpc)
- proto:grpc通信时双方约定接口协议文件,语言无关
- protoc:一个可执行程序,用于根据proto编译成特定语言的grpc文件
- pb:proto经过protoc编译后生成的特定语言文件
- protoc-gen-go:protoc编译时,需要有相关语言的插件(用来生成对应语言的pb文件),protoc自带有java,c++等多种语言的protoc-gen插件,不包含go插件,所以go要另外下载
- go的pb文件生成插件有如下两个
protoc-gen-go
protoc-gen-go-grpc
- 注意下这两个插件目前有两个版本,以前版本是
github
,后面被google
接管,所以后续可以选择
google
的
- `[https://google.golang.org/protobuf/cmd/protoc-gen-go](https://google.golang.org/protobuf/cmd/protoc-gen-go)`
- `[https://github.com/golang/protobuf/protoc-gen-go](https://github.com/golang/protobuf/protoc-gen-go)`
- 注意这两个插件对应下面protoc中的
--go_out
和--go_grpc_out
,分别生成类型pb和service pb- protoc参数:注意生成go的pb时需要前面两个插件
--proto_path=./dir
:代表编译时依赖的proto,若没有指定,则从当前目录下找,该参数可以指定多次,或者简写成-I ./dir
--go_out=plugins=grpc,paths=source_relative:./dir
--go_out
代表生成go的pb文件,如果是生成java的pb,用--java_out
,其他语言类似,且可以使用该参数多次,来生成多种语言pb- 后面的内容分两部分,使用
:
冒号分割 plugins=grpc,paths=source_relative
指定了go插件使用的参数plugins
若指定了grpc,则代表生成的pb文件包含service定义,否则默认只包含类型定义(可以通过--go-grpc_out
插件来单独生成service定义)paths
有两个值import
默认值,代表生成的pb文件的目录为proto中go_package
指定的source_relative
代表生成的pb文件在源proto下
./dir
冒号后面的部分代表pb文件生成的目录- 可以直接指定生成文件目录,不指定插件参数
--go_out=./dir
--go_opt=plugins=grpc,paths=source_relative
该参数目前没找到解释,但是实验过后,应该是指定插件参数,可以取代--go_out
参数的第一部分--go_grpc_out=paths=source_relative:./dir
该参数用于根据proto文件生成service.pb文件,--go_out
参数如果没有加grpc的话只会生成类型pb文件--go_grpc_opt=paths=source_relative
效果如--go_opt
helloword.proto依赖common.proto
syntax = “proto3”;
package proto;
import “comm/common.proto”;
option go_package=”proto/helloworld”;
service Greeter { rpc SayHello (common.Request) returns (common.Response) {} }
编译, 若切换到proto目录, 应该指定—proto_path为上层目录,才能import comm/common.proto
protoc —proto_path=../ —go_out=. ./helloworld.proto
但是执行后会报错
./helloworld.proto: File does not reside within any path specified using —proto_path (or -I). You must specify a —proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names — protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it’s harder than you think).
这是因为当—proto_path指定路径后, 后面的待编译文件./helloworld.proto的搜索路径也会
变成在—proto_path下的路径搜索, 而../这个目录即grpc_demo, 下面不包含./helloworld.proto
所以报错找不到helloworld.proto
可以改成如下两种方式
protoc —proto_path=../ —proto_path=./ —go_out=. ./helloworld.proto protoc —proto_path=../ —go_out=. proto/helloworld.proto
- 同时编译多个proto文件
```shell
└── proto
├── common.proto
├── greeter
│ └── greeter.proto
└── user
└── user.proto
#如上,若想同时编译多个文件,可以使用
protoc --proto_path=. --go_out=. proto/*.proto proto/greeter/*.proto proto/user/*.proto
#不可以直接使用下面的方式,该方式只会编译common.proto
protoc --proto_path=. --go_out=. proto/*.proto
- proto文件参数
syntax
指定协议版本,目前有2和3,两者语法有差别import
指定依赖的文件package
指定proto的包名,用于协议之间的相互依赖。当其他proto引用了这个proto时,使用其中的message时,就是pkg_name.message_name
option go_package
指定生成的pb文件的包路径,每种语言都有对应的参数service
定义服务方法message
定义消息结构,proto2的字段需要optional/required修饰,proto3不用 ```protobuf //comm syntax = “proto3”;
option go_package = “google.golang.org/grpc/examples/helloworld/common”; package comm_pkg;
message CommonMessage { int32 code = 1; string msg = 2; }
//biz syntax = “proto3”;
import “comm/common.proto”; option go_package = “dir1/dir2”;
// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} }
// The request message containing the user’s name. message HelloRequest { comm_pkg.CommonMessage msg = 2; string name = 1; }
<a name="gGlsm"></a>
### Go常用命令
- 如果想要查看某个命令具体用法,可以使用`go help mod graph`
- `go build`用于编译代码,生成可执行文件
```shell
go build #编译当前目录下的文件,生成的可执行文件名根据mod文件确定
go build aaa.go bbb.go #指定编译的文件,生成的可执行文件名为第一个文件
go build -race #开启竞态检测
go build -o newname #指定生成的可执行文件名
go run
编译并运行main函数,但不会产生可执行文件go run . #后面需要跟执行的文件,以及依赖文件,否则会报错找不到依赖
go install
该命令会编译生成可执行文件,同时将文件移动到$GOPATH/bin
目录下go clean
清除编译文件 ```shell go clean -i #清除关联的安装包和可执行文件,即install的内容 go clean -n #输出go clean会执行的命令,仅仅是输出,不会执行 go clean -x #输出并执行所有命令 go clean -cache #清除go build缓存 go clean -testcache #清除测试缓存
如下,指定了-i会清除安装的包,由于加上了-n,只会输出命令,并不执行
go clean -i -n cd /Users/dongxin.chen/goland_space/grpc_demo rm -f grpc_demo grpc_demo.exe grpc_demo.test grpc_demo.test.exe depend depend.exe generator generator.exe main main.exe rm -f /Users/dongxin.chen/go13/go/bin/protoc-gen-go-netrpc
- `go get`可以远程拉取/更新代码包及其依赖包,并自动完成编译安装;内部实际分两步
- 先下载源码包:mod开启时包位于`$GOPATH/pkg/mod/xxx`,关闭时位于`$GOPATH/src`
- 然后执行`go install`,可执行文件位于`$GOPATH/bin/xxx`
- 该命令的执行依赖于代码管理工具(如Git),所以下载的包如果是通过git管理的,需要下载git并加入到$PATH路径下
```shell
go get -d github.com/davyxu/cellnet #只下载不更新
go get -u github.com/davyxu/cellnet #下载丢失的包,但不会更新已存在的包
go test
go fmt
格式化代码go list [包名]
- 用于查看当前目录下的项目包/模块信息
模块(module)
每个项目可以是一个模块,模块名根据mod文件中定义包(package)
每个模块下可以包含很多个包,包不等同于目录,目录下有.go文件才会有包,且包名不一定为目录名。需要注意的是模块根目录的包名是模块名,虽然.go文件中用的是main
-m
默认查询的是包信息,该标志查询模块信息-json
将包/模块的详细信息以json格式显示出来,同时可以配合-f指定显示json中的某些字段,未加该参数时,默认显示的其实也是json中的某个字段-f
可以指定显示json中的某个字段all
当前项目分为主模块/活跃模块两部分,活跃模块可以理解为依赖的模块(mod文件中)
- 用于查看当前目录下的项目包/模块信息
go list
默认显示主模块(当前模块)信息,参数也可以指定具体的模块,或者通过模式匹配。如果
参数为all
,则显示出主模块和活跃模块的所有信息,活跃模块还会显示版本信息
1.项目结构, comm含有go文件, proto没有, 注意go list分析是根据有没有go文件来确定包信息的
grpc_demo
|___comm
|___util
|___util.go
|___common.go
|___proto
|___helloworld.proto
|___main.go
|___go.mod
2. go.mod文件
module go_list_demo
go 1.14
require (
github.com/golang/protobuf v1.5.2
google.golang.org/protobuf v1.26.0 // indirect
)
3. 查看包信息
#默认只会显示当前目录的包,子目录不会显示
☁ grpc_demo go list
go_list_demo
#显示指定目录包信息, 可以看到这种方式相当于后面传啥目录名就显示当前目录下的包信息,不含子目录
☁ grpc_demo go list ./comm
go_list_demo/comm
☁ grpc_demo go list ./comm/util
go_list_demo/comm/util
#模式匹配
☁ grpc_demo go list ./...
go_list_demo
go_list_demo/comm
go_list_demo/comm/util
#显示依赖模块的目录信息
☁ grpc_demo go list google.golang.org/protobuf/...
google.golang.org/protobuf/cmd/protoc-gen-go
google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo
google.golang.org/protobuf/compiler/protogen
...
#显示当前主模块以及依赖模块的包信息
☁ grpc_demo go list all
archive/tar
bufio
bytes
...
4. 查看模块信息
#主模块信息,不包含版本
☁ grpc_demo go list -m
go_list_demo
#依赖模块信息,包含版本, 如果mod中有多个版本,会显示真正用的那个版本, 并不会显示依赖的依赖
☁ grpc_demo go list -m google.golang.org/protobuf
google.golang.org/protobuf v1.26.0
#显示主模块及所有依赖模块信息,包含依赖模块的依赖模块(例如go-cmp就是protobuf依赖的)
#也就是这个项目涉及的所有依赖
☁ grpc_demo go list -m all
go_list_demo
github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.5
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
google.golang.org/protobuf v1.26.0
5. 显示json信息, 上面的命令都可以加上该标志,会将每一行转成如下的json结构
☁ grpc_demo go list -json
{
"Dir": "/Users/dongxin.chen/goland_space/grpc_demo",
"ImportPath": "go_list_demo",
"Name": "main",
"Target": "/Users/dongxin.chen/go13/go/bin/go_list_demo",
"Root": "/Users/dongxin.chen/goland_space/grpc_demo",
"Module": {
"Path": "go_list_demo",
"Main": true,
"Dir": "/Users/dongxin.chen/goland_space/grpc_demo",
"GoMod": "/Users/dongxin.chen/goland_space/grpc_demo/go.mod",
"GoVersion": "1.14"
},
...
}
6. 显示指定字段
☁ grpc_demo go list -f '{{.Name}}' ./...
main
comm
util
7. 显示模块所有可用版本
☁ grpc_demo go list -m -versions github.com/golang/protobuf
github.com/golang/protobuf v1.0.0 v1.1.0 v1.2.0 v1.3.0 v1.3.1 v1.3.2 ...
go mod
可以于管理项目模块信息- 基本的初始化及增删mod文件
go mod graph
可以查看当前项目所有依赖关系(当前项目引入了哪些依赖模块,依赖模块A依赖了哪些模块…),当发生同一个依赖版本冲突时,可以用该命令查找是哪个模块引入的 ```latex ☁ grpc_demo go mod graph go_list_demo github.com/golang/protobuf@v1.5.2 go_list_demo google.golang.org/protobuf@v1.26.0 github.com/golang/protobuf@v1.5.2 github.com/google/go-cmp@v0.5.5 github.com/golang/protobuf@v1.5.2 google.golang.org/protobuf@v1.26.0 google.golang.org/protobuf@v1.26.0 github.com/golang/protobuf@v1.5.0 google.golang.org/protobuf@v1.26.0 github.com/google/go-cmp@v0.5.5 github.com/golang/protobuf@v1.5.0 github.com/google/go-cmp@v0.5.5 github.com/golang/protobuf@v1.5.0 google.golang.org/protobuf@v1.26.0-rc.1 google.golang.org/protobuf@v1.26.0-rc.1 github.com/google/go-cmp@v0.5.5 github.com/google/go-cmp@v0.5.5 golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543
查看google.golang.org/protobuf@v1.26.0依赖哪些模块
☁ grpc_demo go mod graph |grep ‘google.golang.org/protobuf@v1.26.0 ‘ google.golang.org/protobuf@v1.26.0 github.com/golang/protobuf@v1.5.0 google.golang.org/protobuf@v1.26.0 github.com/google/go-cmp@v0.5.5
查看google.golang.org/protobuf@v1.26.0被哪些模块依赖
☁ grpc_demo go mod graph |grep ‘ google.golang.org/protobuf@v1.26.0’ go_list_demo google.golang.org/protobuf@v1.26.0 github.com/golang/protobuf@v1.5.2 google.golang.org/protobuf@v1.26.0 github.com/golang/protobuf@v1.5.0 google.golang.org/protobuf@v1.26.0-rc.1 ```