本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
前言≈
go 之前对第三方包的管理不上心,其他语言比如 python 有 pip,nodejs 有 npm,而 go 却没有一个官方的管理工具。
在 go 1.11 之前,开发者需要要关注 GOPATH 环境变量,这对于开发者来说不友好。
经过几次变更后,go 于 1.12 版本开始正式使用 go Module,go 终于有了一个官方的处理方式,开发者也可以抛弃 GOPATH 了。
本次使用的 go 版本为 1.15.6,建议使用 1.13 或以上的版本,旧的方式就不要再关注了,让它随风而去吧。
go version go1.15.6 darwin/amd64
本次使用的系统为 Ubuntu,实验路径 / opt/golang
root@xxg:/opt/golang# pwd/opt/golang
第三方包
假设我们有个项目叫 caseshow,我们先创建这个目录,并初始化一下
mkdir caseshowcd caseshowgo mod init caseshow
此时在 caseshow 目录下会自动产生一个 go.mod 文件,内容如下:
module caseshowgo 1.15
比如我们想使用一个 redis 客户端:github.com/go-redis/redis/v8,在当前路径下直接执行 go get 命令即可:
go get github.com/go-redis/redis/v8
最近访问 github 很慢,可以先设置一下代理
go env -w GO111MODULE=ongo env -w GOPROXY=https://goproxy.io,direct
设置好之后,下载第三方库
root@xxg:/opt/golang/caseshow# go get github.com/go-redis/redis/v8go: downloading github.com/go-redis/redis v6.15.9+incompatiblego: downloading github.com/go-redis/redis/v8 v8.4.2go: github.com/go-redis/redis/v8 upgrade => v8.4.2go: downloading go.opentelemetry.io/otel v0.14.0go: downloading github.com/cespare/xxhash/v2 v2.1.1go: downloading github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
目录下会多一个 go.sum 文件,go.mod 文件里面也多了关于 redis 库的内容
root@xxg:/opt/golang/caseshow# lsgo.mod go.sumroot@xxg:/opt/golang/caseshow# cat go.modmodule caseshowgo 1.15require github.com/go-redis/redis/v8 v8.4.2 // indirect
之后就可以直接用了,写个 redis.go 测试下:
package mainimport ("context""fmt""github.com/go-redis/redis/v8")var ctx = context.Background()func ExampleClient() {rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "", // no password setDB: 0, // use default DB})err := rdb.Set(ctx, "key", "value", 0).Err()if err != nil {panic(err)}val, err := rdb.Get(ctx, "key").Result()if err != nil {panic(err)}fmt.Println("key", val)val2, err := rdb.Get(ctx, "key2").Result()if err == redis.Nil {fmt.Println("key2 does not exist")} else if err != nil {panic(err)} else {fmt.Println("key2", val2)}// Output: key value// key2 does not exist}func main() {ExampleClient()}
测试正常:
root@xxg:/opt/golang/caseshow# go run redis.gokey valuekey2 does not exist
整个过程没有 GOPATH 什么事。
本地包
在项目开发中会复用本地的一些代码,这就涉及到了本地包的引入。
情况1. 同路径引用其他文件
无需 import,直接使用对应的方法。go build时,在后面加上要用的文件名即可,比如
go build main.go main_command.go
go run调试时,在后面加上要用的文件名即可,比如
go run main.go main_command.go
情况2. 同目录下
在同路径下不能存在多个 package 名,如果要定义其他的 package,可以创建一个对应名字的目录,把代码放下面,之后再引用。
假设在 caseshow 中有个本地开发的包 mymodule,里面有个方法 Pprint,结构如下
# tree.├── go.mod├── go.sum├── mymodule│ └── pprint.go└── redis.go1 directory, 4 files
pprint.go 的代码如下:
package mymoduleimport "fmt"func Pprint(a string){fmt.Println("pprint ", a)}
如果 caseshow 目录下的其他地方要用这个方法,则使用 caseshow + package 名称导入即可。
比如 main.go:
package mainimport "caseshow/mymodule"func main(){mymodule.Pprint("jack")}
直接运行:
# go run main.gopprint jack
情况3. 不同目录下
假设有另一个项目 caselive,与 caseshow 同级,该目录下有个包 yourmodule, 里面有个方法 Yprint:
# tree.├── caselive│ ├── go.mod│ ├── main.go│ └── yourmodule│ └── yprint.go└── caseshow├── go.mod├── go.sum├── main.go├── mymodule│ └── pprint.go└── redis.go4 directories, 8 files
yprint.go 的内容如下:
package yourmoduleimport "fmt"func Yprint(a string){fmt.Println("yprint ", a)}
此时在 caseshow 中要调用 caselive 中 yourmodule 的 Yprint 方法,可以用replace参数来实现。
在 caseshow 的 go.mod 中增加 caselive 的引入:
require mypackage v0.0.0replace mypackage => ../mypackage
完整内容如下:
module caseshowgo 1.15require github.com/go-redis/redis/v8 v8.4.2 // indirectrequire caselive v0.0.0replace caselive => ../caselive
之后就能直接调用了:
package mainimport "caseshow/mymodule"import "caselive/yourmodule"func main(){mymodule.Pprint("jack")yourmodule.Yprint("jack")}
运行测试下:
# go run main.gopprint jackyprint jack
