什么是go modules?

go modules 是 golang 1.11 新加的特性。Modules官方定义为:

模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。

而go mod就是用来管理包的命令。

设置GO111MODULES参数

go mod命令

(可以使用go help mod查看)

创建一个go.mod管理自定义的包

  1. 创建一个greetings目录
  2. 创建greetings.go代码文件,内容如下:
package greetings

import "fmt"

// ***go语言包中的函数如果想要被其他包调用,必须以大写字母开头***
// Hello returns a greeting for the named person.
func Hello(name string) string {
    // Return a greeting that embeds the name in a message.
    message := fmt.Sprintf("Hi, %v. Welcome!", name)
    return message
}

在greetings同级目录中创建hello.go,结构如下

// greeting是目录,hello.go是文件,在一个目录层级中
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2022/4/17     21:30                greetings
-a----         2022/4/17     21:33            152 hello.go

此时没有使用go modules,如果想要像go src里的标准库一样引用自定义的Hello()函数,将会报错,如下图:


正如报错日志所描述,go会从GOROOT和GOAPTH中寻找import的包,但是并没有找到greetings包。

使用go mod init命令创建module

go mod init example.com/greetings
module example.com/greetings

go 1.17
example.com/greetings
package main

import (
    "fmt"

    "example.com/greetings"
)

func main() {
    name := "lisi"
    msg := greetings.Hello(name)
    fmt.Println(msg)
}

从另一个module调用greetings.Hello()

go mod init example.com/hello
cd ..
mkdir hello
cd hello
go mod init example.com/hello

// greetings和hello都是目录
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2022/4/17     21:30                greetings
-a----         2022/4/17     21:33            152 hello.go
d-----         2022/4/17     21:41                hello
greetings.Hello()

hello.go:6:2: no required module provides package example.com/greetings; to add it:
go get example.com/greetings

go get会从指定的url下载对应的包,如果greetings包已经发布,执行该命令可以下载对应的包。但是目前greetings包还在本地未发布,则需要通过以下步骤调用:

  1. 使用以下命令编辑go.mod文件
    go mod edit -replace example.com/greetings=../greetings
    现在hello module的go.mod文件如下:
module example.com/hello

go 1.17

replace example.com/greetings => ../greetings
go mod tidy
\hello> go mod tidy
go: found example.com/greetings in example.com/greetings v0.0.0-00010101000000-000000000000

此时hello/go.mod的内容如下:

module example.com/hello

go 1.17

replace example.com/greetings => ../greetings

require example.com/greetings v0.0.0-00010101000000-000000000000

最后hello.go可以成功调用greetings.Hello()函数