開始編寫GO

預(yù)覽
  • Go程序員通常讓所有的Go代碼在一個單獨(dú)的工作空間(workspace).
  • 一個工作空間包含很多版本控制倉庫(比如虑润,通過git管理)
  • 每個倉庫包含一個或者多個包(packages).
  • 每個包由單獨(dú)的目錄下的Go源文件組成.
  • 包的目錄路徑?jīng)Q定他的導(dǎo)入路徑

注意這是和其他編程環(huán)境不同的地方:每個項(xiàng)目都有單獨(dú)的工作空間,并且工作空間與版本控制倉庫緊密綁定

工作空間

工作根目錄有兩個目錄:

  • src包含夠源文件
  • bin包含可執(zhí)行命令

go tool構(gòu)建并安裝binaries到bin目錄

src子目錄一般包含多個版本控制倉庫(比如Git或者M(jìn)ercurial)追蹤一個或多個源包的開發(fā)搅窿。

下面展示工作空間的結(jié)構(gòu):

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) ...</pre>

上面的樹顯示工作空間包含兩個倉庫(exampleimage)违帆。example倉庫包含兩個命令(hellooutyet)和一把庫(stringutil). image倉庫包含bmp包和其他的一些內(nèi)容

經(jīng)典的工作空間包含多個源倉庫律杠,源倉庫包含多個包和命令簸喂。大多數(shù)的Go程序員將所有的Go源代碼和依賴放在一個單獨(dú)的工作空間。

注意侵续,不應(yīng)該使用symbolic links關(guān)聯(lián)文件或者目錄到工作空間倔丈。

GOPATH環(huán)境變量

GOPATH環(huán)境變量指定工作空間的位置。默認(rèn)是在home目錄里的go目錄状蜗,比如Unix的$HOME/go需五,Windows的%USERPROFILE%\go(通常是C:\Users\YourName\go)。

如果想在不同的地方轧坎,可以使用set GOPATH指定目錄的路徑宏邮。(另一種通用的設(shè)置是GOPATH=$HOME).注意GOPATH一定不能是Go的安裝目錄。

go env命令打印當(dāng)前有效的GOPATH,如果沒有設(shè)置則打印默認(rèn)的位置缸血。

為了方便蜜氨,添加工作空間的bin目錄到你的路徑:

$ export  PATH=$PATH:$(go env GOPATH)/bin

為了簡短,接下來的文檔使用GOPATH代替``(go env GOPATH)捎泻。

導(dǎo)入路徑(Import paths)

import path是唯一的字符串表示包飒炎。包的導(dǎo)入路徑對應(yīng)工作空間里它的位置或者遠(yuǎn)程倉庫位置。

標(biāo)準(zhǔn)庫里的包具有簡短的導(dǎo)入路徑笆豁,比如fmtnet/http郎汪。對于你自己的包,指定的路徑不能與標(biāo)準(zhǔn)庫里的包或者其他內(nèi)部包沖突闯狱。

如果你將代碼保存在源文件倉庫煞赢,那么應(yīng)該使用源倉庫的根目錄作為你的基礎(chǔ)路徑。比如哄孤,如果你有Github賬號照筑,那么github.com/{user}就是你的基本路徑。

注意不要再你能構(gòu)建之前推送代碼到遠(yuǎn)程倉庫瘦陈。

我們將使用github.com/{user}作為你的基礎(chǔ)路徑朦肘。在工作空間下創(chuàng)建一個目錄保存源代碼:

$ mkdir -p $GOPATH/src/github.com/user
第一個程序

要編譯和運(yùn)行一個簡單的程序,先選擇一個包路徑(我們先用github.com/user/hello)并且在工作空間創(chuàng)建相應(yīng)的包目錄:

$ mkdir $GOPATH/src/github.com/user/hello

接下來双饥,在這個目錄下創(chuàng)建一個名為hello.go的文件,包含如下代碼:

package main

import "fmt"

func main() {
    fmt.Println("Hello, world.")
}

現(xiàn)在就可以構(gòu)建并安裝程序了:

$ go install github.com/user/hello

現(xiàn)在你就可以在你的系統(tǒng)里運(yùn)行這個命令了弟断。go tool通過GOPATH指定的工作空間查找github.com/user/hello包的源代碼

如果已經(jīng)在包目錄里咏花,就可以省略掉包路徑

$ cd $GOPATH/src/github.com/user/hello
$ go install

這個命令構(gòu)建hello命令,產(chǎn)生一個可執(zhí)行的binary。然后安裝這個binary到工作空間下的bin目錄昏翰,也就是$HOME/go/bin/hello

go tool只會在有錯誤的時候打印輸出苍匆,所以如果沒有內(nèi)容產(chǎn)生,表示執(zhí)行成功棚菊。

現(xiàn)在可以通過全路徑運(yùn)行程序

$ $GOPATH/bin/hello
Hello, world.
第一個庫

現(xiàn)在我們編寫一個library并且在hello程序里使用浸踩。

同樣,第一步先選擇一個包路徑(我們使用github.com/user/stringutil)先统求,創(chuàng)建包路徑

$ mkdir $GOPATH/src/github.com/user/stringutil

然后創(chuàng)建一個命為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)
}

現(xiàn)在检碗,使用go build測試包編譯:

$ go build github.com/user/stringutil

如果已經(jīng)在包源目錄下,只需要:

go build

這不會產(chǎn)生輸出文件码邻。而是將編譯完的包保存到本地構(gòu)建緩存里折剃。

現(xiàn)在修改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

這一頓操作后,工作空間應(yīng)該變成了:

bin/
    hello                 # command executable
src/
    github.com/user/
        hello/
            hello.go      # command source
        stringutil/
            reverse.go    # package source
Package names

Go源文件里的第一行一定是:

package name

其中name是包的默認(rèn)名稱像屋。
(包中的所有文件必須使用相同的名稱怕犁。)
Go的約定是報名是導(dǎo)入路徑最后一個節(jié)點(diǎn):crypto/rot13的包名是rot13

可執(zhí)行命令的包名必須是package main

不要求包名稱在鏈接到單個二進(jìn)制文件的所有包中都是唯一的己莺,只要導(dǎo)入路徑(它們的完整文件名)是唯一的奏甫。

測試

Go有一個由go test命令和測試包組成的輕量級測試框架。

創(chuàng)建一個用_test.go結(jié)尾的文件凌受,里面的方法命名為TestXXX阵子。測試框架會運(yùn)行每個方法;如果方法調(diào)用失敗方法比如t.Error或者t.Fail胁艰,測試就被認(rèn)為失敗了款筑。

創(chuàng)建一個$GOPATH/src/github.com/user/stringutil/reverse_test.go文件測試stringutil

package stringutil

import "testing"

func TestReverse(t *testing.T) {
    cases := []struct {
        in, want string
    }{
        {"Hello, world", "dlrow ,olleH"},
        {"Hello, 世界", "界世 ,olleH"},
        {"", ""},
    }
    for _, c := range cases {
        got := Reverse(c.in)
        if got != c.want {
            t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
        }
    }
}

然后執(zhí)行go test

$ go test github.com/user/stringutil
ok      github.com/user/stringutil  0.165s
遠(yuǎn)程包

導(dǎo)入路徑可以描述如何使用諸如Git或Mercurial之類的修訂控制系統(tǒng)來獲取包源代碼。go tool使用該屬性自動從遠(yuǎn)程倉庫拉去包腾么。比如奈梳,本文檔里的實(shí)例就保存在github.com/golang/example。如果你在包的導(dǎo)入路徑引入遠(yuǎn)程URL, go get將會自動獲取解虱,構(gòu)建并且安裝它:

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

如果工作空間不存在指定的包攘须,go get會將它放在GOPATH指定的第一個工作空間內(nèi)。(如果包存在殴泰,go get會跳過遠(yuǎn)程獲取于宙,就和go install的行為一樣了)

經(jīng)過上面的操作后,工作目錄結(jié)構(gòu)將會變?yōu)椋?/p>

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

Gihub上托管的hello命令依賴同一倉庫下的stringutil包悍汛。hello.go文件里的imports使用相同的導(dǎo)入路徑規(guī)范捞魁,所以go get命令可以定位并且安裝起來的包:

import "github.com/golang/exmaple/stringutil"

規(guī)范是最簡單的方式讓你的Go包可以對其他的可用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市离咐,隨后出現(xiàn)的幾起案子谱俭,更是在濱河造成了極大的恐慌奉件,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昆著,死亡現(xiàn)場離奇詭異县貌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凑懂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門煤痕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人接谨,你說我怎么就攤上這事摆碉。” “怎么了疤坝?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵兆解,是天一觀的道長。 經(jīng)常有香客問我跑揉,道長锅睛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任历谍,我火速辦了婚禮现拒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘望侈。我一直安慰自己印蔬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布脱衙。 她就那樣靜靜地躺著侥猬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捐韩。 梳的紋絲不亂的頭發(fā)上退唠,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天坡椒,我揣著相機(jī)與錄音躏尉,去河邊找鬼。 笑死榨惰,一個胖子當(dāng)著我的面吹牛仅政,可吹牛的內(nèi)容都是我干的垢油。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼圆丹,長吁一口氣:“原來是場噩夢啊……” “哼滩愁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辫封,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤惊楼,失蹤者是張志新(化名)和其女友劉穎玖瘸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檀咙,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年璃诀,在試婚紗的時候發(fā)現(xiàn)自己被綠了弧可。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡劣欢,死狀恐怖棕诵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凿将,我是刑警寧澤校套,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站牧抵,受9級特大地震影響笛匙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜犀变,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一妹孙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧获枝,春花似錦蠢正、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至懦傍,卻和暖如春雹舀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谎脯。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工葱跋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人源梭。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓娱俺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親废麻。 傳聞我的和親對象是個殘疾皇子荠卷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容