[翻译]Go 怎么样自己写个包

2013/02/03 10:25
阅读数 196

GOPATH and workspaces

One of Go's design goals is to make writing software easier. To that end, the go command doesn't use Makefiles or other configuration files to guide program construction. Instead, it uses the source code to find dependencies and determine build conditions. This means your source code and build scripts are always in sync; they are one and the same.

Go的设计目标中的一项就是让写Go的程序猿爽 尽量地让写Go程序变得简单 所以在go并不需要Makfille 或者是其它的configiure文件来做build 它通过源文件来找到相应的依赖 这就意味着你的源代码和build脚本在任何时候都是一致的 实际上它们已经合体了 

The one thing you must do is set a GOPATH environment variable. GOPATH tells the go command (and other related tools) where to find and install the Go packages on your system.

为了让Go能够解决源代码中的依赖关系 必须要设置一个GOPATH环境变量 GOPATH告知go命令 或者相关的工具在哪里可以找到安装你的系统上的包

GOPATH is a list of paths. It shares the syntax of your system's PATH environment variable. A typical GOPATH on a Unix system might look like this:

GOPATH和linux中的PATH环境变量很像 并且它们之间的语法结构也是一样的 废话啊 都是环境变量嘛 哎 如下这个就是一个典型的替罪羊:


(On a Windows system use semicolons as the path separator instead of colons.)

(Windows系统上 各个path路径是有;来隔开的)

Each path in the list (in this case /home/user/ext or /home/user/mygo) specifies the location of a workspace. A workspace contains Go source files and their associated package objects, and command executables. It has a prescribed structure of three subdirectories:

路径中的每一项(比如/home/user/ext 或者 /home/usr/mygo)都指定了一个workspace的路径 workspace包含Go源文件 相关的包对象 还有可执行命令(稍后有解释 可执行命令):

  • src contains Go source files, src目录包含Go源文件
  • pkg contains compiled package objects, and pkg目录包含已经编译好的包文件
  • bin contains executable commands. bin目录包含可执行命令

Subdirectories of the src directory hold independent packages, and all source files (.go, .c, .h, and .s) in each subdirectory are elements of that subdirectory's package.

src目录下的每一个子目录都是一个独立的包 所有子目录下的源文件 都是所在包的源文件

When building a program that imports the package "widget" the go command looks for src/pkg/widget inside the Go root, and then—if the package source isn't found there—it searches for src/widget inside each workspace in order.

当build一个程序 这个程序导入了一个包“widget” go会在$GOPATH/src/pkg/wigdet这个目录下 寻找相应的包 如果没有的话 就去$GOPATH/src/widget里面去找

Multiple workspaces can offer some flexibility and convenience, but for now we'll concern ourselves with only a single workspace.

多个workspace可以提供更多的灵活性 但是现在我们只需要关心只有一个workspace的情况 

Let's work through a simple example. First, create a $HOME/mygo directory and its src subdirectory:


$ mkdir -p $HOME/mygo/src # create a place to put source code

Next, set it as the GOPATH. You should also add the bin subdirectory to your PATH environment variable so that you can run the commands therein without specifying their full path. To do this, add the following lines to $HOME/.profile (or equivalent):

接下来把之前创建的目录设置为GOPATH 为了执行命令方便 你可以把$HOME/mygo/bin目录添加到PATH中

export GOPATH=$HOME/mygo
export PATH=$PATH:$HOME/mygo/bin                                                                 

Import paths

The standard packages are given short import paths such as "fmt" and "net/http" for convenience. For your own projects, it is important to choose a base import path that is unlikely to collide with future additions to the standard library or other external libraries.

标准包的名字都很简短 比如 “fmt” 和 “net/http” 对于你自己的项目来说 包的查找路径(import path) 非常重要 需要防止和标准库 或者 其它的包重名 傻傻分不清楚

The best way to choose an import path is to use the location of your version control repository. For instance, if your source repository is at example.com orcode.google.com/p/example, you should begin your package paths with that URL, as in "example.com/foo/bar" or "code.google.com/p/example/foo/bar". Using this convention, the go command can automatically check out and build the source code by its import path alone.

最佳的实践是 设置包道路路径为你的版本控制仓库的地址 举个例子来说就是 假如你的版本控制仓库的地址是example.com或者code.google.com/p/example 你应该给你的包加个前缀 example.com/foo/bar 或者 code.google.com/p/example/foo/bar 如果遵守这个惯例 go可以自动地从仓库中check out 并且build源文件

If you don't intend to install your code in this way, you should at least use a unique prefix like "widgets/", as in "widgets/foo/bar". A good rule is to use a prefix such as your company or project name, since it is unlikely to be used by another group.

如果你不想像这样安装你的包 那么你至少得给一个独一无二的前缀 像widgets 可以使用公司名字 或者项目名字作为前缀 这样冲突的可能性会小很多

We'll use example/ as our base import path:


$ mkdir -p $GOPATH/src/example

Package names

The first statement in a Go source file should be

作为包的源文件 第一句话就是告诉go 包的名字

package name

where name is the package's default name for imports. (All files in a package must use the same name.)

name就是包导入的时候默认的名字 所有在同一个包中的文件 都必须使用这个name

Go's convention is that the package name is the last element of the import path: the package imported as "crypto/rot13" should be named rot13. There is no requirement that package names be unique across all packages linked into a single binary, only that the import paths (their full file names) be unique.

Go的惯例是报的名字是包导入路径的最后一段 比如包"crypto/rot13" 那么包的名字就应该是rot13 包的名字并不要求是唯一的 但是包的导入路径必须唯一(这里就是cryptio/rot13是必须唯一的)

Create a new package under example called newmath:

在example下 创建一个包newmath

$ cd $GOPATH/src/example
$ mkdir newmath

Then create a file named $GOPATH/src/example/newmath/sqrt.go containing the following Go code:

在目录$GOPATH/src/example/newmath/下新建一个文件sqrt.go 文件内容如下:

// Package newmath is a trivial example package.
package newmath

// Sqrt returns an approximation to the square root of x.
func Sqrt(x float64) float64 {
        // This is a terrible implementation.
        // Real code should import "math" and use math.Sqrt.
        z := 0.0
        for i := 0; i < 1000; i++ {
                z -= (z*z - x) / (2 * x)
        return z

This package is imported by the path name of the directory it's in, starting after the src component:

当需要导入这个包时 我们可以使用这个import语句:

import "example/newmath"

See Effective Go to learn more about Go's naming conventions.

Building and installing

The go command comprises several subcommands, the most central being install. Running go install importpath builds and installs a package and its dependencies.

go命令包含了很多子命令 比如install 运行go install importpath可以build 并且安装一个包 还有这个包所依赖的其它包也会被build安装

To "install a package" means to write the package object or executable command to the pkg or bin subdirectory of the workspace in which the source resides.

安装一个包的意思是 把包对象 或者 可执行命令 写入到$GOPATH/pkg $GOPATH/bin子目录中

Building a package

To build and install the newmath package, type

build 并且安装newmath这个包

$ go install example/newmath

This command will produce no output if the package and its dependencies are built and installed correctly.

运行这个命令 不要期望有啥输出 最好也别期望有输出 因为有输出反馈的时候 就以为你需要debug了啦

As a convenience, the go command will assume the current directory if no import path is specified on the command line. This sequence of commands has the same effect as the one above:

go为认为当前目录是包导入目录 所以可以cd到$GOPATH/src/example/newmath 然后执行命令 go install来安装包newmath

$ cd $GOPATH/src/example/newmath
$ go install

The resulting workspace directory tree (assuming we're running Linux on a 64-bit system) looks like this:


            newmath.a  # package object
            sqrt.go    # package source

Building a command

The go command treats code belonging to package main as an executable command and installs the package binary to the GOPATH's bin subdirectory.

go会把那些在包main中的代码认为是可执行命令 并且将两进制可执行文件放到$GOPATH/bin目录下

Add a command named hello to the source tree. First create the example/hello directory:

添加一个hello名字 首先创建一个目录example/hello

$ cd $GOPATH/src/example
$ mkdir hello

Then create the file $GOPATH/src/example/hello/hello.go containing the following Go code.

然后 新建一个文件$GOPATH/src/example/hello/hello.go 文件内容如下:

// Hello is a trivial example of a main package.
package main

import (

func main() {
        fmt.Printf("Hello, world.  Sqrt(2) = %v\n", newmath.Sqrt(2))

Next, run go install, which builds and installs the binary to $GOPATH/bin (or $GOBIN, if set; to simplify presentation, this document assumes GOBIN is unset):

最后 运行go install:

$ go install example/hello

To run the program, invoke it by name as you would any other command:

好了 可以运行这个可执行命令了:

$ $GOPATH/bin/hello
Hello, world.  Sqrt(2) = 1.414213562373095

If you added $HOME/mygo/bin to your PATH, you may omit the path to the executable:

如果已经把$/home/mygo/bin添加到了PATH中 你可以直接执行hello命令:

$ hello
Hello, world.  Sqrt(2) = 1.414213562373095

The workspace directory tree now looks like this:


    hello              # command executable
            newmath.a  # package object
            hello.go   # command source
            sqrt.go    # package source

The go command also provides a build command, which is like install except it builds all objects in a temporary directory and does not install them under pkg or bin. When building a command an executable named after the last element of the import path is written to the current directory. When building a package, go build serves merely to test that the package and its dependencies can be built. (The resulting package object is thrown away.)

go命令提供了build子命令 这个子命令和install很像 除了它是在一个临时目录中build所有的对象 并且build完成后并不会安装到相应的pkg, bin目录下 go build一个包 可以仅仅用来测试这个包是否可以通过build 然后它的依赖是否可以被解决



0 收藏
0 评论
0 收藏