学习通过操作来掌握Go模块的使用方法
我看了很多文章,但感觉很难并且有些用英语写的很难理解,所以没有具体的解释,我希望你能通过身体感受来理解它是如何运作的,就像这样写的。
如果我因为自己的知识不足而犯了错误,请告诉我,我会很高兴的。
学习并实践Go的Workspace模式的使用方法
执行环境
-
- M1 Macbook Air
-
- macOS Monterey 12.4
- Go 1.18
只要Windows系统上正常安装了Go,就没问题。
使用方法 (Shǐ
举个例子,有这样的目录结构存在。
% tree
.
├── main
│ └── main.go
└── module
└── module.go
在module.go文件中添加Hello方法。
package module
func Hello() string {
h := "hello"
return h
}
如果想在main模块中使用module的Hello方法,
请在module目录内执行”go mod init”命令。
module % go mod init example.com/module
↑「example.com」的部分,可以使用含有点号的形式,用任何您喜欢的字符来填写。
(最好使用独特(与任何人不重复)的字符。)
(常见的是github.com/您的帐户名/项目名/模块等等)
module exmaple.com/module
go 1.18
go.mod会在module目录下生成。
我会在主目录中以相同的方式创建。
main % go mod init example.com/main
module example.com/main
go 1.18
就像这样,在main.go中按照module/go.mod文件的模块名称进行导入。
package main
import (
"fmt"
"example.com/module"
)
func main() {
fmt.Println(module.Hello())
}
我会尝试在这个状态下先动一次。
前往主目录。
main % go run main.go
main.go:4:2: module example.com/module provides package example.com/module and is replaced but not required; to add it:
go get example.com/module
未发现任何动作。
根据Google翻译,文中写道:”模块example.com/module提供了包example.com/module并可替代,但不是必需的。添加方式是:go get example.com/module”。
那么就按照所说的输入一下试试看吧。
main % go get example.com/module
go get: unrecognized import path "example.com/nodule": reading https://example.com/nodule?go-get=1: 404 Not Found
根据Google翻译的说法:“未知的导入路径example.com/nodule:读取https://example.com/nodule?go-get=1:404未找到”。我再次被指责了。我想可能是因为这是我在本地创建的东西,所以没有URL而被责备了。
就把问题解决了。
在 main/go.mod 文件中添加 replace 语句。
module example.com/main
go 1.18
replace example.com/module => ../module
在main文件夹中,将module/go.mod文件中的module名称替换为实际的module目录的相对路径。
main % go mod tidy
输入下面的内容。
module example.com/main
go 1.18
replace example.com/module => ../module
require example.com/module v0.0.0-00010101000000-000000000000
然后,会在 main/go.mod 文件中添加 require 语句。
通过这样做,可以使自己的模块能够从其他模块中使用。
main % go run main.go
hello
以这种方式,可以使用Hello方法。
最终的目录结构是这样的。
.
├── main
│ ├── go.mod
│ └── main.go
└── module
├── go.mod
└── module.go
将外部包作为module导入并使用的方法
然后,将echo作为外部包导入到server目录中,在main目录中尝试启动服务器。
首先准备一个服务器目录。
目录结构应该是这样的。
├── main
│ ├── go.mod
│ └── main.go
├── module
│ ├── go.mod
│ └── module.go
└── server
└── server.go
请转到服务器目录。
server % go mod init example.com/server
我们将创建一个go.mod文件。
请在server目录下输入以下命令:go get github.com/labstack/echo/v4
server % go get github.com/labstack/echo/v4
go: downloading github.com/labstack/echo v1.4.4
go get: added github.com/labstack/echo/v4 v4.7.2
module example.com/server
go 1.18
require (
github.com/labstack/echo/v4 v4.7.2 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
golang.org/x/text v0.3.7 // indirect
)
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
如果安装得像这样,就可以了。
在server.go文件中进行编写。
package server
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"net/http"
)
func StartServer() {
// Echo instance
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// Routes
e.GET("/", hello)
// Start server
e.Logger.Fatal(e.Start(":1234"))
}
// Handler
func hello(c echo.Context) error {
return c.String(http.StatusOK, "Hello World!")
}
移动到主目录,然后对 main.go 和 go.mod 进行追加操作。
package main
import (
//"example.com/module" コメントアウト
"example.com/server" // 追加
//"fmt" コメントアウト
)
func main() {
//fmt.Println(module.Hello()) コメントアウト
server.StartServer() // 追加
}
module example.com/main
go 1.18
replace (
example.com/module => ../module
example.com/server => ../server // 追加
)
require example.com/module v0.0.0-00010101000000-000000000000
在写多个替换时,可以用括号将其括起来。
完成写作后,在主目录中输入”go mod tidy”。
% go mod tidy
module example.com/main
go 1.18
replace (
example.com/module => ../module
example.com/server => ../server // 追加
)
// example.com/moduleコメントアウトして使用されていないので削除された
// 新しく使用しているexample.com/serverが追加された!
require example.com/server v0.0.0-00010101000000-000000000000
require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/labstack/echo/v4 v4.7.2 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
)
如果以这样的方式进行添加,那就可以了。
让我们尝试启动服务器吧。
main % go run main.go
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.7.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1234
在目前的状态下,如果你转到http://localhost:1234/,应该会显示“Hello World!”。
我认为最终的结果会是这样的目录结构。
.
├── main
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── module
│ ├── go.mod
│ └── module.go
└── server
├── go.mod
├── go.sum
└── server.go
总结
我认为这个模块管理是学习Go语言时的一个难点。这次我写的目的是为了让大家能够在实际运行中理解,因为仅靠语言很难传达清楚。所以,如果可以的话,请大家在自己的电脑上尝试运行一下。
这是我们这次制作的源代码,如果方便的话,也请您在这里确认一下。
以下是我参考的网站