go-booker

135 阅读4分钟

Go

docs

go env

$GOROOT

golang的安装目录,本地安装目录; GOROOT="/Users/a002/GolandProbjects/go1.13.5"

$GOPATH

go项目的管理目录,允许配置多个目录,但默认使用第一个,全局配置=>GOPATH="/Users/a002/GolandProbjects"

有三个子目录

  • src:源码(.go .c .h .s)
  • pkg:编译中间文件(.a)
  • bin:可执行文件

建议无论是使用命令行或者使用集成开发环境编译 Go 源码时,GOPATH 跟随项目设定。 在 Jetbrains 公司的 GoLand 集成开发环境(IDE)中的 GOPATH 设置分为全局Global GOPATH 和项目 Probject GOPATH; 建议在开发时只填写项目Probject GOPATH,每一个项目尽量只设置一个GOPATH,一个项目不同时使用GOPATH和全局的GOPATH.

$GOBIN

编译后可执行文件目录,默认是$GOPATH/bin

#GOPRIVATE

需要使用GOPRIVATE配置私有库或项目的地址

$GOPROXY

公有Go模块镜像的代理地址,默认为proxy.golang.org

project manager

project namning

在$GOPATH/src目录下probjectname; 默认约定main.go是可执行应用,用来部署;probjectname.go是依赖应用,用来打包

  • projectname
    • config
    • controller
    • service
    • repository
    • entity/proto
    • router
      • middleware
    • util
    • ventor
    • main.go || probjectname.go

访问控制规则由命名决定

当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Analysize,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private)

  • :包名应该为小写单词,不要使用下划线或者混合大小写

  • 文件/测试文件:应该为小写单词,使用下划线分隔各个单词; xxx_yyy.go; xxx_yyy_test.go

  • 单元测试: 单元测试文件名命名规范为 example_test.go 测试用例的函数名称必须以Test开头,例如:TestExample 每个重要的函数都要首先编写测试用例,测试用例和正规代码一起提交方便进行回归测试 。

  • 变量/函数/结构体: 使用驼峰,首字母大写=public,首字母小写=private;单词不能缩写,特有名词(url)开头的变量要全部小写或大写:urlArray,URLArray

  • 常量: 使用全大写,加下划线 const CACHE_APP,统一前缀;

  • bool变量,则名称应以 has/is/can/allow开头

  • 参数:对于大量数据的struct可以考虑使用指针;参数传入参数是map,slice,chan不要传递指针,因为map,slice,chan是引用类型,不需要传递指针的指针

  • 错误处理

    • 错误处理的原则就是不能丢弃任何有返回err的调用,不要使用 _丢弃,必须全部处理。接收到错误,要么返回err,或者使用log记录下来
    • 尽早return:一旦有错误发生,马上返回
    • 尽量不要使用panic,除非你知道你在做什么
    • 错误描述如果是英文必须为小写,不需要标点结尾
    • 采用独立的错误流进行处理

go dep manager

可用的工具选择

  1. govendor + GOPATH
  2. dep
  3. glide
  4. go mod

govendor

govendor官网

move from vender to mod

rm -rf vendor
go mod init
go mod tidy

dep

dep-git

dep-官网

  • Gopkg.lock: 是生成的文件,不要手工修改;
  • Gopkg.toml: 是依赖管理的核心文件,可以生成也可以手动修改,一般情况下Gopkg.toml里面只定义直接依赖项,而Gopkg.lock里面除了包含Gopkg.toml中的所有项之外,还包含传递依赖项。比如我们的项目依赖项目A, 而项目A又依赖B、C,那么只有A会包含在Gopkg.toml中,而A、B、C都会定义在Gopkg.lock中。所以Gopkg.lock定义了所有依赖的项目的详细信息(commit ID和packages),使得每次build我们自己的项目时,始终基于确定不变的依赖项。
  • vendor: 是 golang1.5 以后依赖管理目录,这个目录的依赖代码是优先加载的,类似 node 的 node_module 目录。

glide

glide

go-module

# 1. go module cmd
$ go version # >=1.11
$ GO111MODULE=on #设置环境变量,default=auto;on/off/auto
$ go mod 查看帮助提示
# 2. Goland 设置
# 3. govendor 兼容
$ govendor add +external拷贝到vendor目录中(govendor init)
GO111MODULE

auto 或者不设置—默认设置,会根据执行命令的目录是否有go.mod文件来确定是否使用module-mode; on — 执行命令的目录强制使用moudle-mode; off — 执行命令的目录强制不使用moudle-mode;

go-mudule-usage
  1. $GOPATH/src路径变化 go help modules文档说明:When using modules, GOPATH is no longer used for resolving imports. However, it is still used to store downloaded source code (in GOPATH/pkg/mod) and compiled commands (in GOPATH/bin)
  • 环境变量GOPATH不再用于解析imports包路径,即原有的GOPATH/src/下的包,通过import是找不到了
  • Go Module功能开启后,下载的包将存放与$GOPATH/pkg/mod路径
  • $GPATH/bin路径功能保持之前的一样
  1. 新增go.mod文件管理依赖
  2. 引入Go Module之后,go get命令又重新实现了。

不开启Go Module功能,go get代码实现$GOROOT/src/cmd/go/internal/get/get.go; 开启Go Module功能,go get代码实现 $GOROOT/src/cmd/go/internal/modget/get.go

最直接的区别是:

  1. 老的go get取包过程=git clone + go install,开启Go Module功能后go get就只有 git clone(download)过程了
  2. 新老实现还有一个不同是,两者存包的位置不同。前者存放GOPATH/src目录下;后者存放在GOPATH/src目录下;后者存放在GOPATH/pkg/mod目录下
  3. 老的go get取完主包后,会对其repo下的submodule进行循环拉取。新的go get不再支持submodule子模块拉取。

vscode config

  1. github.com/golang/vsco…
  2. github.com/golang/vsco…
  3. github.com/golang/vsco…
  4. github.com/golang/vsco…

go.inferGopath=true

支持的配置: 全局/用户/工作区(.vscode/setting.json)

// go 安装目录
"go.goroot": "/Users/a002/GolandProbjects/go1.13.5",
// 默认全局工作区
// "go.gopath": "/Users/a002/GolandProbjects",
// 指定当前工作区目录,需要绝对路径
"go.gopath"="${workspaceRoot}"
// 第三方工具目录
"go.toolsGopath": "/Users/a002/GolandProbjects",
// This setting is useful when you are working on different Go projects which have different GOPATHs. Instead of setting the GOPATH in the workspace settings of each project or setting all the paths as ;/: separated string, you can just set go.inferGopath to true and the extension uses the right GOPATH automatically.
// false: 使用全局gopath
// true: 当前项目使用自己的gopath; 即: ${workspaceRoot}/x,如果项目是x/src/main.go
"go.inferGopath":true,

go.toolGopath=gopath

  • 我们知道go编译生成的bin文件会默认放在GOPATH/bin下,那么如果vscode为每个项目单独指定了(“工作区设置”)自己的“go.gopath”,这就覆盖了系统环境的GOPATH

  • 而我们命令行中go getgo install安装的bin文件默认是放在系统环境GOPATH/bin下。因此项目单独设置的“go.gopath”下的bin文件夹下是没有那些在系统环境下已经安装好的bin文件的,于是vscode会提示你当前这个独立设置的项目缺少依赖的第三方包,需要安装。

  • 但其实我们系统环境GOPATH/bin下已经装过了,你可以拷贝到单独项目的gopath/bin下。更简便的做法是vscode用户设置里,设置"go.toolsGopath" = "全局$GOPATH"即可.

vscode-go-module-support

ERROR: The "inferGopath" setting is disabled for this workspace because Go modules are being used. ERROR: $GOPATH/go.mod exists but should not