视频版在本文的最后
1. go 1.16引发的血案
一直在用go语言做一个编译器项目,从go 1.10开始使用。里面涉及到一堆自己写的本地模块,都用go写的,然后通过GOPATH设置这些模块的搜索路径,其实这么做没问题。只不过go从1.11开始,推出了新的依赖管理模块go modules,只不过google为了给大家一个适应期,一直到go 1.15,默认仍然使用的是GOPATH,除非按如下方式设置环境变量GO111MODULE。
GO111MODULE=on
由于从GOPATH模式改成go modules模式需要配置go.mod文件,而且每一个模块都需要配置,比较麻烦,所以也懒得弄。但到了go1.16,google竟然将GO111MODULE的默认值改成了on。只不过只有windows是这样(linux没测试,不太清楚默认是on还是其他值),而macOS下GO111MODULE的默认值是auto。所以在macOS下与go 1.15表现一样。但我需要开发跨平台的编译器,所以在windows下编译直接报了如下错误。
package core is not in GOROOT (/usr/local/go/src/core)
在go modules模式下,go编译器将不会考虑GOPATH中的模块路径,所以只会到go的安装目录去搜索,因此解决的方式有如下两个:
(1)将GO111MODULE变量的值改成off或auto
(2)直接使用go modules模式
但第1种有问题,因为从go 1.17开始,google将永久去掉GO111MODULE变量,也就是说,从go 1.17开始,go modules模式你用也得用,不用也得用。所以还是赶紧将自己的go工程切换到go modules模式吧!
如果大家引用的是网络模块,相信网上已经有很多资料讲如何配置go modules,而本文主要讲如何在go modules模式中配置本地模块。
2. 在go modules中配置本地模块
要做这个实验,首先要将你的go版本升级到go 1.11或以上版本,推荐使用最新的go 1.16。由于本文使用goland做这个实验,所以需要安装goland。
现在使用goland创建一个新的go工程,接下来按下面的步骤操作:
(1)在工程中创建一个libs目录,用于保存模块文件。
(2)在libs目录中创建一个Greet.go文件,并输入如下的代码:
package libs
func Greet(name string) string {
return "hello " + name
}
(3)在工程根目录创建TestGreet.go文件,并输入如下代码:
package main
import "libs"
import "fmt"
func main() {
fmt.Printf(libs.Greet("Bill"))
}
如果在这时执行TestGreet.go,肯定会抛出如下错误:
package libs is not in GOROOT (/usr/local/go/src/libs)
这是因为go编译器还无法找到libs下的Greet.go文件。如果这时GO111MODULE的值是on或auto,即使设置了GOPATH环境变量也不好使。这是因为如果使用go modules模式,go编译不会再考虑GOPATH环境变量中的模块路径,而且GOPATH模式还有一个限制,就是要求模块必须在搜索路径的src目录中,而本例未创建src目录,所以即使是GOPATH模式,也无法搜索到Greet.go文件。
下面来配置go modules模式
(4)在libs目录下创建一个go.mod文件,并输入下面的内容:
module libs
go 1.16
如果不想自己创建,使用下面的命令自动创建go.mod文件也可以。
go mod init libs
这里的libs是模块名,其实模块名叫什么都可以,甚至可以是域名或目录结构,如unitymarvel.com/libs也可以,就是个名字而已,后面会使用这个名字。
如果GO111MODULE变量的值是auto,并且发现模块下有go.mod文件,就会自动切换到go modules模式。
(5)在工程根目录创建一个go.mod文件,并输入下面的内容:
module testgreet go 1.16 replace libs => ./libs
这里的“libs”表示(4)中设置的模块名,而“./libs”表示Greet.go所在的路径。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
图片转存中…(img-1tEdbrLc-1725990767628)]
[外链图片转存中…(img-Ymul5DQY-1725990767628)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!