模块化代码在 Go 中是如何工作的?

Posted

技术标签:

【中文标题】模块化代码在 Go 中是如何工作的?【英文标题】:How does modular code work in Go? 【发布时间】:2011-11-05 11:51:09 【问题描述】:

我没有 C/编译语言背景,我发现很难掌握使用 Go 的包机制来创建模块化代码。

在 Python 中,导入一个模块并访问它的函数等等,这是一个简单的例子

import foo

其中 foo.py 是您要在同一目录中导入的模块的名称。否则,您可以将空的__init__.py 添加到子文件夹中并通过

from subfolder import foo

然后您可以通过简单地通过模块名称引用函数来访问函数,例如y = foo.bar(y)。这使得将逻辑代码段彼此分离变得很容易。


然而,在 Go 中,您在源文件本身中指定包名,例如

package foo

在 'foo' 模块的顶部,然后你可以通过它导入

import (
        "foo"
              )

然后通过它来引用它,即y := foo.Bar(x)。但我无法理解的是这在实践中是如何工作的。 golang.org 上的相关文档看起来很简洁,并且针对的是具有更多(任何)使用 makefile 和编译器经验的人。

有人能清楚地解释一下您打算如何在 Go 中模块化您的代码、这样做的正确项目结构以及编译过程是如何工作的吗?

【问题讨论】:

我将回复一个指向示例存储库的链接,该链接显示了这个漏洞交易。 github.com/jteeuwen/go-example-multipkg希望能有所帮助。为我的 github thingy 的无耻的自我插件道歉,但这比在 SO 上复制它更好。 对于 Go 模块(Go 1.11 中的新功能),许多相同的答案仍然适用,但这个 answer 更多地涵盖了 Go 模块的这个问题。 【参考方案1】:

维基答案,请随意添加/编辑。

模块化

    同一个包中的多个文件

    听起来就是这样。同一目录中的一堆文件都以相同的 package <name> 指令开头,这意味着它们被 Go 视为一大组代码。您可以从b.go 透明地调用a.go 中的函数。这主要是为了代码组织的好处。 一个虚构的例子是一个“博客”包可以用blog.go(主文件)、entry.goserver.go布局。由你决定。虽然您可以在一个大文件中编写博客包,但这往往会影响可读性。

    多个包

    标准库就是这样完成的。基本上,您创建模块并选择将它们安装到$GOROOT。你写的任何程序都可以import "<name>"然后调用<name>.someFunction() 在实践中,任何独立或共享的组件都应该编译成包。回到上面的博客包,如果要添加新闻提要,可以将 server.go 重构为一个包。那么blog.gonews.go 都将是import "server"

编译

我目前将 gomake 与 Makefile 一起使用。 Go 安装附带了一些很棒的 make 包含文件,可以简化包或命令的创建。这并不难,掌握这些内容的最佳方法就是查看来自开源项目的示例 makefile 并阅读 "How to Write Go Code"。

【讨论】:

好的,这确实清除了很多,谢谢!但是您是否必须为包中的每个文件重新声明导入? 可能,但编译器会在您丢失或不需要导入时告诉您。【参考方案2】:

除了包组织,和python中的pip一样,使用dephttps://github.com/golang/dep进行go包管理。如果你在现有的 go 包上使用它,它将自动构建依赖关系树,其中包含所有正在使用的包的版本。转移到生产服务器时,dep ensure 将使用 Gopkg.toml 安装所有必需的包。 只需使用 dep ensure -add ,其他用于 dep 的命令是:

Commands:

    init     Set up a new Go project, or migrate an existing one
    status   Report the status of the project's dependencies
    ensure   Ensure a dependency is safely vendored in the project
    version  Show the dep version information
    check    Check if imports, Gopkg.toml, and Gopkg.lock are in sync

 Examples:
    dep init                               set up a new project
    dep ensure                             install the project's dependencies
    dep ensure -update                     update the locked versions of all dependencies
    dep ensure -add github.com/pkg/errors  add a dependency to the project

【讨论】:

以上是关于模块化代码在 Go 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

标头在 Objective-C 中是如何工作的?

c语言中是如何实现模块化的

VS Code 向我显示“加载工作区时出错:在工作区中两次找到模块“main.go””

Go 1.18 新特性多模块工作区教程

如何从Dep迁移到Go模块

Go 1.18 新特性:多模块工作区模式