前言
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 caseshow
cd caseshow
go mod init caseshow
此时在caseshow目录下会自动产生一个go.mod文件,内容如下:
module caseshow
go 1.15
比如我们想使用一个redis客户端:github.com/go-redis/redis/v8,在当前路径下直接执行go get命令即可:
go get github.com/go-redis/redis/v8
最近访问github很慢,可以先设置一下代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct
设置好之后,下载第三方库
root@xxg:/opt/golang/caseshow# go get github.com/go-redis/redis/v8
go: downloading github.com/go-redis/redis v6.15.9+incompatible
go: downloading github.com/go-redis/redis/v8 v8.4.2
go: github.com/go-redis/redis/v8 upgrade => v8.4.2
go: downloading go.opentelemetry.io/otel v0.14.0
go: downloading github.com/cespare/xxhash/v2 v2.1.1
go: downloading github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
目录下会多一个go.sum文件,go.mod文件里面也多了关于redis库的内容
root@xxg:/opt/golang/caseshow# ls
go.mod go.sum
root@xxg:/opt/golang/caseshow# cat go.mod
module caseshow
go 1.15
require github.com/go-redis/redis/v8 v8.4.2 // indirect
之后就可以直接用了,写个redis.go测试下:
package main
import (
"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 set
DB: 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.go
key value
key2 does not exist
整个过程没有GOPATH什么事。
本地包
在项目开发中会复用本地的一些代码,这就涉及到了本地包的引入。
情况0 同路径引用其他文件
无需import,直接使用对应的方法。go build
时,在后面加上要用的文件名即可,比如
go build main.go main_command.go
go run
调试时,在后面加上要用的文件名即可,比如
go run main.go main_command.go
情况1 同目录下
在同路径下不能存在多个package名,如果要定义其他的package,可以创建一个对应名字的目录,把代码放下面,之后再引用。
假设在caseshow中有个本地开发的包mymodule,里面有个方法Pprint,结构如下
# tree
.
├── go.mod
├── go.sum
├── mymodule
│ └── pprint.go
└── redis.go
1 directory, 4 files
pprint.go的代码如下:
package mymodule
import "fmt"
func Pprint(a string){
fmt.Println("pprint ", a)
}
如果caseshow目录下的其他地方要用这个方法,则使用caseshow + package名称导入即可。
比如main.go:
package main
import "caseshow/mymodule"
func main(){
mymodule.Pprint("jack")
}
直接运行:
# go run main.go
pprint jack
情况2 不同目录下
假设有另一个项目caselive,与caseshow同级,该目录下有个包yourmodule,里面有个方法Yprint:
# tree
.
├── caselive
│ ├── go.mod
│ ├── main.go
│ └── yourmodule
│ └── yprint.go
└── caseshow
├── go.mod
├── go.sum
├── main.go
├── mymodule
│ └── pprint.go
└── redis.go
4 directories, 8 files
yprint.go的内容如下:
package yourmodule
import "fmt"
func Yprint(a string){
fmt.Println("yprint ", a)
}
此时在caseshow中要调用caselive中yourmodule的Yprint方法,可以用replace
参数来实现。
在caseshow的go.mod中增加caselive的引入:
require mypackage v0.0.0
replace mypackage => ../mypackage
完整内容如下:
module caseshow
go 1.15
require github.com/go-redis/redis/v8 v8.4.2 // indirect
require caselive v0.0.0
replace caselive => ../caselive
之后就能直接调用了:
package main
import "caseshow/mymodule"
import "caselive/yourmodule"
func main(){
mymodule.Pprint("jack")
yourmodule.Yprint("jack")
}
运行测试下:
# go run main.go
pprint jack
yprint jack
最新评论