go modules简单使用及踩坑
相信每个gopher在刚接触golang的时候都会遇到过go get失败的情况,尤其是golang.org下的包,过去也许最常用的方法是到github上拉取对应的包。
随着Go1.13正式发布两个多月,go module越来越成熟,可能过去经常因为某些原因导致各种package下载失败,现在是时候和go path说再见了。
步骤
在项目根目录
go mod init [module_name]
建议module与项目同名(最好与远程仓库同名),否则本地包引用会很混乱
运行go mod将生成go.mod文件,默认格式如下
//go.mod
module [module_name]
go 1.13
这时我尝试下载依赖包发现仍然失败
执行go env,发现下面两条相关配置
GO111MODULE=""
GOPROXY="https://proxy.golang.org,direct"
由于GOPROXY默认值为https://proxy.golang.org ,在国内是无法访问的
因此将其修改为goproxy.io或goproxy.cn或阿里云
打开终端并执行
go env -w GOPROXY=https://goproxy.cn,direct
1.12及更早的版本需要
export GOPROXY=https://goproxy.cn
GOPROXY支持设置为多个proxy的列表(逗号分隔),Go编译器会按顺序尝试列表中的proxy,但是当有proxy server服务不可达或者是返回的http状态码不是404也不是410时,go会终止数据获取;返回404或410时,Go编译器会尝试直接连接依赖module的代码托管站点以获取数据
这里我以为就大功告成了,结果又报go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules',原来是因为没有设置GO111MODULE
当值为auto时如果在gopath路径下的项目是不支持go mod的
因此将其设为on
go env -w GO111MODULE=on
用mysql测试一下,本地mysql -u root -p 123456
//test.go
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, _ := sql.Open("mysql", "root:[email protected]/test?charset=utf8")
if err := db.Ping(); err != nil {
fmt.Println("open database fail")
return
}
fmt.Println("connect success")
}
执行go run或go build时将会自动下载mysql驱动包
同时go.mod中会自动生成一条依赖信息以及go.sum
//go.mod
require github.com/go-sql-driver/mysql v1.4.1
大功告成!
如果引入本地项目中的包时报错
build xxx: cannot load xxx/yyy: malformed module path "xxx/yyy": missing dot in first path element
其实开始init mod的时候项目与module同名的话是不会出现这种错误的,如果设置了不同的名字,import的时候需要更改为module的名字
目前有些IDE可能会报红,不过并不影响正常执行
import (
//"project_name/具体的package"
"module_name/具体的package"
)