gpt4 book ai didi

go - 使用 Go 模块在包中组织本地代码

转载 作者:IT王子 更新时间:2023-10-29 01:16:30 27 4
gpt4 key购买 nike

我找不到从 main.go 中分解出一些代码的方法在 $GOPATH 之外使用 Go 模块(go 版本 >= 1.11)时进入本地包.

我没有导入任何需要包含到 go.mod 中的外部依赖项,我只是想在本地整理这个 Go 模块的源代码。

文件main.go :

package main

// this import does not work
import "./stuff"

func main() {
stuff.PrintBaz()
}

文件./stuff/bar.go (伪装成本地包):

package stuff

import "log"

type Bar struct {
Baz int
}

func PrintBaz() {
baz := Bar{42}
log.Printf("Bar struct: %v", baz)
}

文件go.mod (命令 go mod init foo ):

module foo

go 1.12

执行go run main.go时:

  • 如果我import "./stuff" ,然后我看到 build command-line-arguments: cannot find module for path _/home/<PATH_TO>/fooprj/stuff .
  • 如果我import "stuff" ,然后我看到 build command-line-arguments: cannot load stuff: cannot find module providing package stuff .
  • 如果我import stuff "./stuff"使用包别名,然后我再次看到:build command-line-arguments: cannot find module for path _/home/<PATH_TO>/fooprj/stuff .

我找不到让本地包与 go 模块一起工作的方法。

  • 上面的代码有什么问题?
  • 如何将本地包导入到使用 Go 模块定义的项目(文件 go.mod)中的其他 Go 代码中?

最佳答案

模块结构

最常见和最简单的方法是:

  • 每个存储库使用一个 go.mod,并且
  • 将单个 go.mod 文件放在存储库根目录中,然后
  • 使用存储库名称作为 go.modmodule 行中声明的模块路径
    • (如果您使用的是 custom import path,例如 me.io/mymod 而不是使用基于 VCS 主机的导入路径,那么您将使用自定义导入路径而不是存储库名称你的 go.mod)。

例如,如果你的 repo 是 github.com/my/repo,那么你将在 repo 根目录中放置一个 go.mod,第一行阅读 module github.com/my/repo。这可以通过 cd'ing 到 repo root 并运行 go mod init github.com/my/repo 来创建。

遵循这一点可以帮助您在使用模块的过程中保持愉快的状态,并且可以避免多重微妙之处。

Russ Cox 在 #26664 中发表评论:

For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.

"Multi-module Repositories" 中有更多关于多模块存储库的信息模块 wiki 上的常见问题解答部分。任何考虑改变上述建议的人都应该完整阅读该部分中的那 6 个左右的常见问题解答。

在模块中安排包

一旦你设置好你的 go.mod,你就可以在包含 go.mod 的目录下面的目录中安排你的包,因为以及包含 go.mod 的目录中。关于如何在包中安排代码的三篇好文章:

这些文章是模块引入之前的经典文章,但其中的理念仍然适用于如何在模块中安排包。

在同一模块中导入其他包

当导入另一个带有模块的包时,您总是使用包括模块路径在内的完整路径。即使在同一个模块中导入另一个包也是如此。例如,如果一个模块在其 go.mod 中将其身份声明为模块 github.com/my/repo,并且您拥有以下组织:

repo/
├── go.mod <<<<< Note go.mod is located in repo root
├── pkg1
│   └── pkg1.go
└── pkg2
└── pkg2.go

然后 pkg1 会将其对等包导入为 import "github.com/my/repo/pkg2"。请注意,您不能使用相对导入路径,例如import "../pkg2"import "./subpkg"。 (这是 OP 在上面使用 import "./stuff" 的一部分)。

模块与存储库与包与导入路径

Go 模块是相关 Go 包的集合,它们作为一个单元一起进行版本控制。模块记录精确的依赖需求并创建可重现的构建。

总结存储库、模块和包之间的关系:

  • 存储库 包含一个或多个 Go 模块(最常见的是存储库根目录中的一个模块)。
  • 每个模块包含一个或多个 Go
  • 每个包都包含一个或多个 Go 源文件,它们都位于一个单个目录中。
  • 去源代码:
    • 使用 package foo 语句声明自己的包。
    • 自动访问同一包中的其他 Go 源代码。
    • 通过导入语句中提供的导入路径从另一个包导入代码,例如import "github.com/my/repo/pkg1"。导入路径始终以该包的模块路径开头,无论该包是在同一模块还是不同模块中。

关于go - 使用 Go 模块在包中组织本地代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55442878/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com