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

huangapple go评论89阅读模式
英文:

How does modular code work in Go?

问题

没有来自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中模块化代码,正确的项目结构以及编译过程是如何工作的?

英文:

Not having come from a C/compiled languages background, I'm finding it hard to get to grips with using Go's packages mechanism to create modular code.

In Python, to import a module and get access to it's functions and whatnot, it's a simple case of

import foo

where foo.py is the name of the module you want to import in the same directory. Otherwise you can add an empty __init__.py into a subfolder and access the modules via

from subfolder import foo

You can then access functions by simply referencing them through the module name, e.g. y = foo.bar(y). This makes it easy to separate logical pieces of code from one another.


In Go however, you specify the package name in the source file itself, e.g.

package foo

at the top of the 'foo' module, which you can then supposedly import through

import (
        "foo"
              )

and then refer to it through that, i.e. y := foo.Bar(x) . But what I can't wrap my head around is how this works in practice. The relevant docs on golang.org seem terse, and directed to people with more (any) experience using makefiles and compilers.

Can someone please clearly explain how you are meant to modularise your code in Go, the right project structure to do so, and how the compilation process works?

答案1

得分: 22

模块化

  1. 同一个包中的多个文件

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

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

编译

我目前使用带有 Makefile 的 gomake。Go 安装包含了一些很棒的用于 make 的包含文件,简化了包或命令的创建。这并不难,最好的方法是查看开源项目中的示例 makefile,并阅读《如何编写 Go 代码》。

英文:

Wiki answer, please feel free to add/edit.

Modularization

  1. Multiple files in the same package

    • This is just what it sounds like. A bunch of files in the same directory that all start with the same package <name> directive means that they are treated as one big set of code by Go. You can transparently call functions in a.go from b.go. This is mostly for the benefit of code organization.
    • A fictional example would be a "blog" package might be laid out with blog.go (the main file), entry.go, and server.go. It's up to you. While you could write a blog package in one big file, that tends to affect readability.
  2. Multiple packages

    • The standard library is done this way. Basically you create modules and optionally install them into $GOROOT. Any program you write can import "<name>" and then call <name>.someFunction()
    • In practice any standalone or shared components should be compiled into packages. Back to the blog package above, If you wanted to add a news feed, you could refactor server.go into a package. Then both blog.go and news.go would both import "server".

Compilation

I currently use gomake with Makefiles. The Go installation comes with some great include files for make that simplify the creation of a package or a command. It's not hard and the best way to get up to speed with these is to just look at sample makefiles from open source projects and read "How to Write Go Code".

答案2

得分: 1

除了包组织之外,像Python中的pip一样,使用dep(https://github.com/golang/dep)来管理Go包。如果你在现有的Go包上使用它,它将自动构建使用的所有包的版本依赖树。当切换到生产服务器时,dep ensure将使用Gopkg.toml安装所有所需的包。
只需使用dep ensure -add <包名>,dep的其他命令包括:

命令:

init     设置一个新的Go项目,或迁移现有项目
status   报告项目依赖的状态
ensure   确保依赖安全地存储在项目中
version  显示dep的版本信息
check    检查导入、Gopkg.toml和Gopkg.lock是否同步

示例:
dep init 设置一个新项目
dep ensure 安装项目的依赖
dep ensure -update 更新所有依赖的锁定版本
dep ensure -add github.com/pkg/errors 向项目添加一个依赖

英文:

In addition to the package organisation, Like pip in python, use dep https://github.com/golang/dep for go package management. if you use it on existing go package it will automatically build the dependency tree with versions for all the packages being used. when shifting to production server, dep ensure will use Gopkg.toml to install all the required packages.
Just use dep ensure -add <package name>, other commands for dep are:

Commands:

    init     Set up a new Go project, or migrate an existing one
    status   Report the status of the project&#39;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&#39;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

huangapple
  • 本文由 发表于 2011年8月28日 22:09:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/7221463.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定