[譯] 經過官網 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…
相關文章
相關標籤/搜索