[译] 经过官网 Go 语言学习笔记 | How to Write Go Code

原文:How to Write Go Codehtml

一些基本概念

  1. 下载 & 安装:golang.org/doc/install
  2. go tool:安装好 Go 以后自带的 cmd 工具,用于 fetch, build and install Go packages.
  3. workspace:每个 Go 的项目代码都存储在一个 workspace 里
  4. 一个 workspace 可能包含多个版本管理的 repository(后面用 repo 简写)
  5. 每个 repo 里可能包含一个或多个 packages
  6. 每个 package 在一个文件夹里包含一个或多个 Go 源码文件
  7. 一个 package 的文件夹路径就是它的 import path

go tool 对代码的组织结构有特定的要求 git

Workspaces

Def: 一个 workspace 是一个有特定文件结构 hierarchy 的文件夹,其中根目录下有两个文件夹:github

  • src:包含 Go 源代码
  • bin:包含可执行命令

go tool 会构建(build)和安装(install)可执行代码(binaries)到 bin 文件夹中。src 文件夹下的子文件夹即会包含多个 repo。golang

For Example:bash

bin/
    hello                          # command executable
    outyet                         # command executable
src/
    github.com/golang/example/
        .git/                      # Git repository metadata
	hello/
	    hello.go               # command source
	outyet/
	    main.go                # command source
	    main_test.go           # test source
	stringutil/
	    reverse.go             # package source
	    reverse_test.go        # test source
    golang.org/x/image/
        .git/                      # Git repository metadata
	bmp/
	    reader.go              # package source
	    writer.go              # package source
    ... (many more repositories and packages omitted) ...
复制代码

GOPATH 环境变量

DefGOPATH 环境变量指向了你的 workspace 的位置。它在 Unix 的默认值是在你 Home 文件夹下的 $HOME/go 或是 Windows 里的 %USERPROFILE%\go(一般是 C:\Users\YourName\go)。工具

若是你但愿设置多个不一样的位置,能够经过设置 GOPATH 来解决。学习

GOPATH 不能与安装 Go 的位置同样 fetch

能够经过 go env GOPATH 看到目前的 GOPATHui

开放 workspace's 里的 bin 子目录到 PATH(就是在 $GOPATH/bin/ 下的 cmd 能够直接调用了):spa

$ export PATH=$PATH:$(go env GOPATH)/bin
复制代码

设置 $GOPATH 到环境变量:

$ export GOPATH = $(go env GOPATH)
复制代码

Import paths

Def: 一个 import path 是表明一个 package 的惟一指代字段(String)。一个 package 的 import path 表明了其在一个 workspace 中的具体位置(也多是一个远程 repo)。

  • Standard library 中的 packages:能够用 short import paths 来引入,如:"fmt""net/http"
  • 本身项目中的 packges:必须选择一个 base path 且避免与潜在其余 package、标准库 package、外部 package 有名字冲突。
  • 远程 repo:使用远程 repo 的根地址为 base path。如:一个 GitHub 的用户名 github.com/user 做为 base path

在咱们本身的电脑上,咱们能够先设置一个 base path(注意,这里 user 你能够本身随便写):

$ mkdir -p $GOPATH/src/github.com/user
复制代码

第一个 Program

咱们来开发第一个项目,咱们假设这个 package path 是 github.com/user/hello 并创建一个子文件夹做为 package 的文件夹:

$ mkdir $GOPATH/src/github.com/user/hello
复制代码

下一步则是创建一个文件 hello.go 做为源代码:

package main

import "fmt"

func main() {
    fmt.Println("Hello, world.")
}
复制代码

下一步就是用 go tool 来 build 和 install 这段代码:

$ go install github.com/user/hello
复制代码

这个命令会触发:

  1. 找到 package 的位置:
  • go tool 首先会经过 base path + package name 找到 workspace 里(由于 GOPATH 环境变量已经设置了 workspace 的位置)相应的 package path github.com/user/hello
  • 若是你当前的文件夹在 package path 中,即 $ cd $GOPATH/src/github.com/user/hello,那么就能够直接输入 $ go install 便可
  1. 构建 hello 命令,并生成一个可执行的 binary 文件
  2. 安装这个 binary 文件到 workspace 的 bin 文件夹下并命名为 hello,即 $GOPATH/bin/hello
  • 若是你上面已经经过把 $GOPATH/bin 加入到 $PATH 环境变量里,那么 hello 已经能够做为命令使用。

也就是以下效果:

$ $GOPATH/bin/hello
Hello, world.
复制代码

$ hello
Hello, world.
复制代码

第一个 Library

一样,像是创建一个 Program 同样,咱们创建一个 Library 文件夹 stringutil

$ mkdir $GOPATH/src/github.com/user/stringutil
复制代码

而后在 stringutil 文件夹里创建一个文件 reverse.go

// Package stringutil contains utility functions for working with strings.
package stringutil

// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
	r := []rune(s)
	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return string(r)
}
复制代码

也如同上面所说,咱们来构建(build)它,逐一这里咱们只 build 不 install 由于这是一个 Library:

$ go build github.com/user/stringutil
复制代码

构建好后,若是咱们想在咱们的 Program 中引用这个 stringutil Library 则经过更新 GOPATH/src/github.com/user/hello 中的 hello.go 文件:

package main

import (
	"fmt"

	"github.com/user/stringutil"
)

func main() {
	fmt.Println(stringutil.Reverse("!oG ,olleH"))
}
复制代码

下一步,咱们从新 install hello

$ go install github.com/user/hello
复制代码

那么相应的 cmd hello 经过引用 stringutil Library 也有了新的输出:

$ hello
Hello, Go!
复制代码

这时,若是咱们看 workspace 中的变化和文件结构就是:

bin/
    hello                 # command executable
src/
    github.com/user/
        hello/
            hello.go      # command source
        stringutil/
            reverse.go    # package source
复制代码

其中:

  • bin/hello 是 install 以后的可执行 binary 程序
  • github.com/user/hellohello Program
  • github.com/user/stringutilstringutil Library

Package names

每个 Go 源代码文件的第一行必须是:

package name
复制代码

而这里 name 是 package 被引用时的默认名。在 Go 语言的常规使用中,import path 的最后一个元素即为 package name,例如:package 经过 "crypto/rot13" 引用,那么这个 package 的名字应该是 rot13

可运行的 cmd(也就是要被 install)的 binary 名必须是 main。而 package name 并不必定要不重复,只要 import paths 惟一便可。也就是 "util1/util""util2/util" 是不一样的。

Testing

此处内容精炼,这里不作阐述了。

Remote packages 远程 packages

一个 import path 能够用来获取一个远程的 package(如 Git 或 Mercurial),go tool 会自动下载远程的 repo。例如,Go 官方的示例代码被存储在 GitHub 上,地址为 github.com/golang/example,使用 go get 命令便可自动 fetch, build and install,go get 会将 package 自动下载到 $GOPATH 中的第一个 workspace 中:

$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!
复制代码

这个时候的 workspace 文件夹结构变成了:

bin/
    hello                           # command executable
src/
    github.com/golang/example/
	.git/                       # Git repository metadata
        hello/
            hello.go                # command source
        stringutil/
            reverse.go              # package source
            reverse_test.go         # test source
    github.com/user/
        hello/
            hello.go                # command source
        stringutil/
            reverse.go              # package source
            reverse_test.go         # test source
复制代码

这个时候,你可能会疑虑,就是 hello 以前是由 github.com/user/hello来定义的,而如今被 github.com/golang/example/hello 覆盖。

NEXT

  1. Effective Go 学习如何写出规范的 Go 代码: golang.org/doc/effecti…
  2. A Tour of Go 学习语言: tour.golang.org/
  3. 官方文档:golang.org/doc/

References:

  1. Go Website: golang.org/
  2. How to Write Go Code: golang.org/doc/code.ht…
  3. Set GOPATH: golang.org/wiki/Settin…
相关文章
相关标签/搜索