


























包
一般来说,开发项目时,可以把相关功能的代码集中放在某个包里面。例如在main包目录中新建一个 calc包,将所有计算函数都放在其中,以供别的代码调用。
同一个目录就是同一个包,该包内go文件里的变量、函数、结构体互相可见,可以直接使用。
跨目录就是跨包,使用时需要导入别的包,导入需要指定该包的路径。
包管理
GOPATH Go 1.11版本之前,项目依赖包存于GOPATH。GOPATH是一个环境变量,指向一个目录,其中存放项 目依赖包的源码。 GOPATH缺省值是 家目录/go 。 开发的代码放在 GOPATH/src 目录中,编译这个目录的代码,生成的二进制文件放到 GOPATH/bin 目录 下。 这会有以下问题:
GOPATH不区分项目,代码中任何import的路径均从GOPATH作为根目录开始。如果有多个项目, 不同项目依赖不同库的不同版本,这就很难解决了
所有项目的依赖都放在GOPATH中,很难知道当前项目的依赖项是哪些
GOPATH + vendor机制
Go 1.5引入vendor机制。
vendor:将项目依赖包复制到项目下的vendor目录,在编译时使用项目下的vendor目录的包进行编译。 依然不能解决不同项目依赖不同包版本问题
包搜索顺序:
Go Modules
Go Modules是从Go 1.11版本引入,到1.13版本之后已经成熟,Go Modules成为官方的依赖包管理解决方案。
优势:
GO111MODULE配置
GO111MODULE控制Go Module模式是否开启,有off、on、auto(默认)三个值,auto是默认值。
GO111MODULE=on ,支持模块,Go会忽略GOPATH和vendor目录,只根据go.mod下载依赖,在 $GOPATH/pkg/mod目录搜索依赖包。 Go 1.13后默认开启,不支持模块,Go会从GOPATH和vendor目录寻找包 GO111MODULE=auto ,在 $GOPATH/src 外面构建项目且根目录有go.mod文件时,开启模块支持。 否则使用GOPATH和vendor机制
GOPROXY环境变量可以指定包下载镜像(镜像地址有时会变化)
GOPROXY=https://goproxy.cn,direct
GOPROXY=https://mirrors.aliyun.com/goproxy/
GOPROXY=https://mirrors.cloud.tencent.com/go/
GOPROXY=https://repo.huaweicloud.com/repository/goproxy/
Module模式
go mod命令
在Go 1.11开始引入,可以在任何目录使用go.mod创建项目
go mod vendor 把第三方依赖包复制到项目的vendor目录中,就可以离线使用该依赖包编译。
构建Module模式项目
构建项目根目录magtools,并初始化模块 go mod init magedu.com/tools ,会产生go.mod文件,内容如下:
module cabel go 1.20 require ( github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect )
module: 指定模块名称
go: 指定当前模块使用的Go版本
require: 依赖
根目录下新建main.go,内容如下:
package main import "fmt" func main() { fmt.Println("hello magedu.com") }
package 指定包名,同一个目录包名必须相同
import 导入包。这里是绝对导入,且fmt是标准库中的包(标准库搜索 $GOROOT/src)
main函数,必须在main包中,且只能有一个main函数。如果要编译成可执行文件,必须要有 main函数
import关键字
1、绝对导入和别名导入
import ( "fmt" "test.com/tools/calc" "test.com/tools/calc/minus" // 绝对导入 m "git.com/tools/calc/minus" // 别名导入 ) calc.Add(4, 10) minus.Minus(10, 20) m.Minus()
2、点导入
把包内所有导出成员直接导入到本地。很少使用,很有可能导入的标识符导致冲突。
import . "test.com/tools/calc/minus" // 使用举例 Minus()
go-staticcheck对于点导入会有警告, should not use dot imports (ST1001)go-staticcheck 。参 看 should not use dot imports (ST1001)go-staticcheck。
3、匿名导入
import _ "magedu.com/tools/calc/minus"
使用下划线作为别名,就意味着无法使用了,这种情况下,只能执行导入的包内的所有init函数了。主要作用是做包的初始化用。
init函数
init函数主要是做一些初始化工作。但是由于同一个包里面init函数执行顺序不可预期,所以,除非有必 要,不要在同一个包里面定义多个init。init和main函数不一定在同一个文件中。
导入第三方包
拉取模块依赖后,会发现多出了一个 go.sum 文件,其详细罗列了当前项目直接或间接依赖的所有模块 版本,并写明了那些模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版 本不会被篡改。
指令说明
参考 https://golang.google.cn/ref/mod#go-mod-file-require
require:用于设置一个特定的模块版本 // indirect:该注释表示该模块为间接依赖,也就是在当前应用程序中的
import 语句中,并 没有发现这个模块的明确引用,有可能是你先手动 go get 拉取下来的,也有可能是你所依赖 的模块所依赖的
exclude:用于从使用中排除一个特定的模块版本 replace:用于将一个模块版本替换为另外一个模块版本
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。