Programmer

Will Change The World

使用go module时遇到的坑

  1.  获取依赖包失败
package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.New()

	r.GET("/", func(c *gin.Context) {
		c.Writer.Write([]byte("hello world"))
	})

	r.Run("127.0.0.1:8080")
}

执行go build命令后,结果如下:

qinghe@localhost:~/go/src/test$ ls
go.mod  main.go
qinghe@localhost:~/go/src/test$ go build 
build test: cannot load github.com/gin-gonic/gin: module github.com/gin-gonic/gin: Get https://goproxy.golang.org/github.com/gin-gonic/gin/@v/list: dial tcp 216.239.37.1:443: connect: connection refused

因为安装go后,默认的GOPROXY环境变量为https://goproxy.golang.org,而这个代理在国内是无法访问的,因此会报错。

最新的1.13.3版本默认的GOPROXY值为https://goproxy.golang.org,direct,也即通过代理不通后会尝试直连,只要不是拉取墙外包的话,一般是没问题的了。另外,GOSUMDB也存在同样的问题,因此强烈建议安装Go后的第一步就是修改这两个环境变量的值:

export GOPROXY=https://goproxy.cn,direct
export GOSUMDB=sum.golang.google.cn  #此地址未被墙

2. 主版本变更

go modules采取了十分激进的策略,要求所有的项目都采用语义化版本(semantic version)发布。因此认为v1+和v1版本不兼容,所以在go modules看来v1和v1+是完全不同的modules,导入时的module名称也不同。

例如,在导入v1或v0版本时:

go.mod:

module  mymodule

require (
    github.com/user/pkg  v1.0.1
)

导入v2版本时就要在module名后加上v2:

module mymodule

require (
     github.com/user/pkg/v2  v2.0.1
)

不光在go.mod中需要在module名称后加上主版本号,在import语句中同样也要加上主版本号:

package main

import "github.com/user/pkg/v2"

func main(){

    pkg.Hello()

}

但是这里要注意,import后面是package的路径, 在使用时,还是要使用package名,即:pkg.Hello()

因为v1和v2属于不同的module,所以项目中允许不同主版本的module同时存在:

package main

import (
    "github.com/user/pkg"
    v2 "github.com/user/pkg/v2"
)

func main (){
    pkg.Hello()
    v2.Hello()
}

但是执行了go mod vendor时,不同主版本的依赖库如何共存在一个vendor目录中呢?答案是:放在v2目录中。

例如下面的module:

pkg
├── go.mod
├── main.go
└── subpkg
├── bar.go
└── foo.go

v2版本:

pkg
└── v2
├── go.mod
├── main.go
└── subpkg
├── bar.go
└── foo.go

放在vendor目录中共存:

pkg
 ├── go.mod
 ├── main.go
 ├── subpkg
 │   ├── bar.go
 │   └── foo.go
 └── v2
     ├── go.mod
     ├── main.go
     └── subpkg
         ├── bar.go
         └── foo.go
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注