How does modular code work in 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开发者_JAVA技巧 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?
Wiki answer, please feel free to add/edit.
Modularization
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 ina.go
fromb.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
, andserver.go
. It's up to you. While you could write a blog package in one big file, that tends to affect readability.
- This is just what it sounds like. A bunch of files in the same directory that all start with the same
Multiple packages
- The standard library is done this way. Basically you create modules and optionally install them into
$GOROOT
. Any program you write canimport "<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
andnews.go
would bothimport "server"
.
- The standard library is done this way. Basically you create modules and optionally install them into
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".
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 , 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'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
精彩评论