npmcomposerMavenGradle
Depofficial experiment
go1.11go module
VendorGoVendorGoDepDepGlide
关于Workspaces和GOPATH
go1.11go get
WorkspacesGOPATH
GOPATH
$ echo $HOME
/Users/wangtom
$ export GOPATH=$HOME/go
GOPATH
$ go env |grep GOPATH
GOPATH="/Users/wangtom/go"
开启 GO111MODULE:
GO111MODULEGO111MODULE=on
# 使用 go 命令设置
$ go env -w GO111MODULE=on
# linux / mac
$ export GO111MODULE=on
$ go env |grep GO111MODULE
GO111MODULE="on"
从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具,不需要再手动设置 GO111MODULE=on 了。
GO111MODULE=automodulesmodulesGO111MODULEon
$ export GO111MODULE=on
$ go mod init github.com/cnwyt/mylib
go: creating new go.mod: module github.com/cnwyt/mylib
创建一个公用模块 mylib 模块
mylib
github.com/cnwyt/mylib
$GOPATH/src/github.com
创建一个目录mylib目录,并进入该命令:
$ mkdir -p $GOPATH/src/github.com/cnwyt/mylib
$ cd $GOPATH/src/github.com/cnwyt/mylib
go mod init
~/dev/go-demo
$ mkdir mylib
$ cd mylib
$ go mod init github.com/cnwyt/mylib
go: creating new go.mod: module github.com/cnwyt/mylib
$ ls
go.mod
$ cat go.mod
module github.com/cnwyt/mylib
go 1.19
go.modpackage.jsoncomposer.json
创建一个名为util的公共包,公共包我们一般放置放在项目的 pkg 目录下:
# mylib/pkg/util/hello.go
package util
import "fmt"
func SayHello() {
fmt.Println("nihao -- from mylib")
}
在main函数中调用,
package main
import (
"fmt"
// <----- 这里引入本项目的 utl 包
// 路径与使用 go mod init初始化时的 module 名称一致
"github.com/cnwyt/mylib/pkg/util"
)
func main() {
fmt.Println("Hello, mylib!")
// <----- 这里调用本项目的 utl 包的方法
util.SayHello()
}
go mod
| 命令 | 作用 |
|---|---|
| go mod init | 初始化当前文件夹,创建 go.mod 文件 |
| go mod edit | 编辑 go.mod 文件 |
| go mod tidy | 增加缺少的包,删除无用的包 |
| go mod download | 下载依赖包到本地(默认在 GOPATH/pkg/mod 目录) |
| go mod graph | 打印模块依赖图 |
| go mod vendor | 将依赖复制到 vendor 目录下 |
| go mod verify | 校验依赖 |
| go list -m all | 查看所有的依赖 |
创建一个本地模块 appdemo , 并调用 mylib:
在 GOPATH 以外的目录里,创建一个 appdemo 的应用目录,作为自己的项目目录。
因为作为应用目录不需要别人调用,不需要放到网上,因此不加 github.com 域名,直接起个 mod 名字即可,这里起的名字是 appdemo,和该项目的目录同名。
$ mkdir appdemo && cd appdemo
$ go mod init appdemo
go: creating new go.mod: module appdemo
$ vi main.go
创建一个 main.go 文件:
package main
import "fmt"
func main() {
fmt.Println("Hello, appdemo!");
}
在 appdemo 项目,我们也创建一个名为 util 的公共包(该包仅供该项目里共用),公用包我们一般放置放在项目的 pkg 目录下:
# mylib/pkg/util/hello.go
package util
import "fmt"
// UnixTime time()
func UnixTime() int64 {
return time.Now().Unix()
}
在 main.go 里调用:
package main
import (
"fmt"
// <----- 这里引入本项目的 utl 包
// 路径与使用 go mod init初始化时的 module 名称一致
"pkg/util"
)
func main() {
fmt.Println("Hello, mylib!")
// <----- 这里调用本项目的 utl 包的方法
t := util.UnixTime()
fmt.Println("timestamp: ", t)
}
调用前边的公用模块 mylib:
github.com/cnwyt/myliblatest
$ go mod init appdemo
$ go mod edit -require github.com/cnwyt/mylib@latest
查看 go.mod 文件。
$ cat go.mod
module appdemo
go 1.19
require github.com/cnwyt/mylib v0.0.0
go build
$ go build
# <---- 可能是这个报错:
build appdemo: cannot find module for path github.com/cnwyt/mylib
# <---- 可能是这个,找不到这个mylib,报错:
go: errors parsing go.mod:
Confirm the import path was entered correctly.
这是为啥呢?
GOPATH
cnwyt/mylibcnwyt/mylib
go replace
可以使用 go mod edit 命令修改。或直接修改 go.mod 文件,新增一行 replace:
module helloworld
require github.com/cnwyt/mylib v0.0.0
replace github.com/cnwyt/mylib => /Users/wangtom/dev/go-example/go-mod-demo/mylib
v0.0.0
package main
import (
"appdemo/pkg/util"
"fmt"
// <----- 这里引入 公共模块 mylib 的 util 包
// <----- 因为与项目里的util包重名了,所以重命名为 util2
util2 "github.com/cnwyt/mylib/pkg/util"
)
func main() {
fmt.Println("hello app demo")
timestamp := util.UnixTime()
fmt.Println("timestamp: ", timestamp)
// <----- 这里调用 公共模块 mylib
util2.SayHello()
}
然后重新运行,可以看到可以正常调用 mylib 里的方法:
$ go run main.go
hello app demo
timestamp: 1666147320
nihao -- from mylib
调用已存在的第三方模块
这里演示调用第三方模块 Redis 操作库 go-redis/redis。
使用 go get 下载安装 go-redis/redis:
$ go get github.com/go-redis/redis/v8
go: added github.com/cespare/xxhash/v2 v2.1.2
go: added github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
go: added github.com/go-redis/redis/v8 v8.11.5
go buildgo testgo.mod
如果下载不下来代码,可以设置goproxy模块代理(七牛云提供)。
# Go 1.13 及以上(推荐)
# 打开你的终端并执行
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
查看 go.mod 文件变化:
module appdemo
go 1.19
require github.com/cnwyt/mylib v0.0.0
require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
)
replace github.com/cnwyt/mylib => /Users/wangtom/dev/go-example/go-mod-demo/mylib
$GOPATH/pkg/mod/
$ ls $GOPATH/pkg/mod/github.com/go-redis
redis
redis@v6.15.9+incompatible
代码示例:
import (
"context"
"github.com/go-redis/redis/v8"
"fmt"
)
var ctx = context.Background()
func main() {
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
}
参考链接
END
路漫漫其修道远,吾将上下而求索。
欢迎访问 我的博客