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)

  1. <a name="ukh8P"></a>
  2. ### MySQL中的int(M)
  3. - MySQL建表时,对于整数字段,有如下几类
  4. - tinyint:占一个字节
  5. - smallint:占两个字节
  6. - mediumint:占三个字节
  7. - int/integer:占四个字节,这两个类型都是同一个,只是写法区别
  8. - bigint:占八个字节
  9. - 对于整数类型,通常建表时,我们会在后面加上(M),这个叫做显示宽度,与字段的存储长度无关,存储长度仍然由前面的类型决定;当存储的数值位数小于M时,显示时会补0,超过则不会,且只有对字段指定了`zerofill`才会生效。
  10. - 如下,可以看到123由于不够5位,会补0。注意显示宽度只会影响数据查看显示而已,不会影响存储,且需要对字段制定了`zerofill`才会生效
  11. - 另外吐槽下goland自带的mysql client这个显示宽度不生效,直接是默认int(10)
  12. ```sql
  13. mysql> create table zerofill_test (
  14. id int primary key,
  15. user_id int(5) zerofill
  16. )ENGINE=innodb, CHARSET=utf8
  17. mysql> insert into zerofill_test value (1, 123)
  18. mysql> insert into zerofill_test value (1, 12356)
  19. mysql> select * from zerofill_test;
  20. +----+---------+
  21. | id | user_id |
  22. +----+---------+
  23. | 1 | 00123 |
  24. | 2 | 123456 |
  25. +----+---------+

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

  1. - `[https://google.golang.org/protobuf/cmd/protoc-gen-go](https://google.golang.org/protobuf/cmd/protoc-gen-go)`
  2. - `[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
    • 引入依赖文件,若proto需要依赖其他proto,可以在proto中使用import,同时注意protoc编译时,要指定好--proto_path或-I参数,否则可能找不到import的依赖文件。注意指定--proto_path后,待编译的目标proto的搜索路径也会基于这些路径搜索 ```shell

      文件目录

      └── grpc_demo ├── comm └── common.proto └── proto └── helloword.proto

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

  1. - 同时编译多个proto文件
  2. ```shell
  3. └── proto
  4. ├── common.proto
  5. ├── greeter
  6. │ └── greeter.proto
  7. └── user
  8. └── user.proto
  9. #如上,若想同时编译多个文件,可以使用
  10. protoc --proto_path=. --go_out=. proto/*.proto proto/greeter/*.proto proto/user/*.proto
  11. #不可以直接使用下面的方式,该方式只会编译common.proto
  12. 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; }

  1. <a name="gGlsm"></a>
  2. ### Go常用命令
  3. - 如果想要查看某个命令具体用法,可以使用`go help mod graph`
  4. - `go build`用于编译代码,生成可执行文件
  5. ```shell
  6. go build #编译当前目录下的文件,生成的可执行文件名根据mod文件确定
  7. go build aaa.go bbb.go #指定编译的文件,生成的可执行文件名为第一个文件
  8. go build -race #开启竞态检测
  9. go build -o newname #指定生成的可执行文件名
  • go run编译并运行main函数,但不会产生可执行文件

    1. 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

  1. - `go get`可以远程拉取/更新代码包及其依赖包,并自动完成编译安装;内部实际分两步
  2. - 先下载源码包:mod开启时包位于`$GOPATH/pkg/mod/xxx`,关闭时位于`$GOPATH/src`
  3. - 然后执行`go install`,可执行文件位于`$GOPATH/bin/xxx`
  4. - 该命令的执行依赖于代码管理工具(如Git),所以下载的包如果是通过git管理的,需要下载git并加入到$PATH路径下
  5. ```shell
  6. go get -d github.com/davyxu/cellnet #只下载不更新
  7. 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. 1.项目结构, comm含有go文件, proto没有, 注意go list分析是根据有没有go文件来确定包信息的
  2. grpc_demo
  3. |___comm
  4. |___util
  5. |___util.go
  6. |___common.go
  7. |___proto
  8. |___helloworld.proto
  9. |___main.go
  10. |___go.mod
  11. 2. go.mod文件
  12. module go_list_demo
  13. go 1.14
  14. require (
  15. github.com/golang/protobuf v1.5.2
  16. google.golang.org/protobuf v1.26.0 // indirect
  17. )
  18. 3. 查看包信息
  19. #默认只会显示当前目录的包,子目录不会显示
  20. grpc_demo go list
  21. go_list_demo
  22. #显示指定目录包信息, 可以看到这种方式相当于后面传啥目录名就显示当前目录下的包信息,不含子目录
  23. grpc_demo go list ./comm
  24. go_list_demo/comm
  25. grpc_demo go list ./comm/util
  26. go_list_demo/comm/util
  27. #模式匹配
  28. grpc_demo go list ./...
  29. go_list_demo
  30. go_list_demo/comm
  31. go_list_demo/comm/util
  32. #显示依赖模块的目录信息
  33. grpc_demo go list google.golang.org/protobuf/...
  34. google.golang.org/protobuf/cmd/protoc-gen-go
  35. google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo
  36. google.golang.org/protobuf/compiler/protogen
  37. ...
  38. #显示当前主模块以及依赖模块的包信息
  39. grpc_demo go list all
  40. archive/tar
  41. bufio
  42. bytes
  43. ...
  44. 4. 查看模块信息
  45. #主模块信息,不包含版本
  46. grpc_demo go list -m
  47. go_list_demo
  48. #依赖模块信息,包含版本, 如果mod中有多个版本,会显示真正用的那个版本, 并不会显示依赖的依赖
  49. grpc_demo go list -m google.golang.org/protobuf
  50. google.golang.org/protobuf v1.26.0
  51. #显示主模块及所有依赖模块信息,包含依赖模块的依赖模块(例如go-cmp就是protobuf依赖的)
  52. #也就是这个项目涉及的所有依赖
  53. grpc_demo go list -m all
  54. go_list_demo
  55. github.com/golang/protobuf v1.5.2
  56. github.com/google/go-cmp v0.5.5
  57. golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
  58. google.golang.org/protobuf v1.26.0
  59. 5. 显示json信息, 上面的命令都可以加上该标志,会将每一行转成如下的json结构
  60. grpc_demo go list -json
  61. {
  62. "Dir": "/Users/dongxin.chen/goland_space/grpc_demo",
  63. "ImportPath": "go_list_demo",
  64. "Name": "main",
  65. "Target": "/Users/dongxin.chen/go13/go/bin/go_list_demo",
  66. "Root": "/Users/dongxin.chen/goland_space/grpc_demo",
  67. "Module": {
  68. "Path": "go_list_demo",
  69. "Main": true,
  70. "Dir": "/Users/dongxin.chen/goland_space/grpc_demo",
  71. "GoMod": "/Users/dongxin.chen/goland_space/grpc_demo/go.mod",
  72. "GoVersion": "1.14"
  73. },
  74. ...
  75. }
  76. 6. 显示指定字段
  77. grpc_demo go list -f '{{.Name}}' ./...
  78. main
  79. comm
  80. util
  81. 7. 显示模块所有可用版本
  82. grpc_demo go list -m -versions github.com/golang/protobuf
  83. 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 ```