2017-04-19 15 views
2

看看這個shell會話,我在Go中創建一個簡單的hello world程序。

$ cd ~/lab/hello/ 
$ ls 
hello.go 
$ cat hello.go 
package main 

import "fmt" 

func main() { 
    fmt.Printf("hello, world\n") 
} 
$ go build 
$ ./hello 
hello, world 
$ go env 
GOARCH="amd64" 
GOBIN="" 
GOCHAR="6" 
GOEXE="" 
GOHOSTARCH="amd64" 
GOHOSTOS="linux" 
GOOS="linux" 
GOPATH="" 
GORACE="" 
GOROOT="/usr/lib/go" 
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" 
CC="gcc" 
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0" 
CXX="g++" 
CGO_ENABLED="1" 
$ lsb_release -a 
No LSB modules are available. 
Distributor ID: Debian 
Description: Debian GNU/Linux 8.7 (jessie) 
Release: 8.7 
Codename: jessie 

這是我不明白。教程https://golang.org/doc/install#testing說我應該把我的hello.go文件放在〜/ go/src/hello。但我沒有遵循這一點。我的程序如何編譯呢?如果我的程序以這種方式編譯,那麼爲什麼文檔說我應該保留我的源代碼在〜/ go/src或$ GOPATH/src中,這似乎不重要?

有沒有一種情況下,真的有必要將源代碼放在$ GOPATH/src?

+3

嘗試[創建一個庫](https://golang.org/doc/code.html#Library)。 –

+2

閱讀[如何寫代碼](https://golang.org/doc/code.html),它解釋了所有這些。 – JimB

+0

@MadWombat遵循經過測試,驗證,推薦的方式「有些愚蠢」?如果一臺機器的設計者告訴你:「你必須先按這個按鈕,然後你才能做X.」你是否還會問有什麼證據可以首先按下按鈕? 「工具的創造者告訴你這樣做」沒有足夠的證據?那麼,可能不是自我在編程方面那麼強大。 – Volker

回答

4

標準Go工具請查看$GOPATH子目錄src,pkgbin。例如,

currency.go

package main 

import (
    "fmt" 
    "time" 

    "golang.org/x/text/currency" 
) 

func main() { 
    t1799, _ := time.Parse("2006-01-02", "1799-01-01") 
    for it := currency.Query(currency.Date(t1799)); it.Next(); { 
     from := "" 
     if t, ok := it.From(); ok { 
      from = t.Format("2006-01-01") 
     } 
     fmt.Printf("%v is used in %v since: %v\n", it.Unit(), it.Region(), from) 
    } 
} 

輸出:

$ go build currency.go 
currency.go:7:2: cannot find package "golang.org/x/text/currency" in any of: 
    /home/peter/go/src/golang.org/x/text/currency (from $GOROOT) 
    /home/peter/gopath/src/golang.org/x/text/currency (from $GOPATH) 
$ 

如果我們把丟失的包$GOPATH/src,標準轉到工具會發現它。

$ go get golang.org/x/text/currency 
$ go build currency.go 
$ ./currency 
GBP is used in GB since: 1694-07-07 
GIP is used in GI since: 1713-01-01 
USD is used in US since: 1792-01-01 
$ 
1

正如JimB在他的評論中說的那樣,Go documentation說得很清楚;基本上,GOPATH是工作區它允許您將所有項目文件和導入以及工件保留在一個位置。

對於一個簡單的項目來說,它不是絕對必要的,但是當您開始導入依賴關係並希望管理庫時,它變得更有幫助。

0

真的需要把你的代碼放在一個GOPATH一旦你寫了一個以上的package main。當你import "github.com/me/myapp/mylib",Go會看你的GOPATH。像go test這樣的工具也可以根據GOPATH下的包而不是.go文件進行工作。

只要您的代碼位於多個文件中,它也會變得更實際。這就像直接調用cc/gcc/etc編譯C程序的區別。並使用像make這樣的工具。

如果你是新手,不知道人們爲什麼要分手項目分成多個包擺在首位,原因包括:

  • 項目發展,並且通過10K或100K線你真的需要整理。
  • 項目通常包含可重複使用的工具,並且軟件包會讓其他項目分開執行。
  • 使用軟件包可以跟蹤和控制哪些代碼可以訪問其他代碼和變量。例如,一個包中的私有名稱對於其他包是不可訪問的,因此您知道可以在不破壞包之外的代碼的情況下處理私有內容,並且您知道外部代碼不會使用私有字段/變量或調用私人代碼背後。
  • 包最小化命名空間衝突,即,您可以有gzip.Readerio.Reader。如果你選擇正確的名字,packagename.ThingName可以使代碼自然閱讀。
  • 可以單獨重新編譯,測試等軟件包,這可以使編輯/構建/測試周期更快。
  • 特別是,軟件包強制執行一些其他有關代碼組織的事情,例如沒有循環依賴關係(如果A導入B,B不直接或間接導入A),並且/foo/internal/下的軟件包僅被/foo/下的軟件包使用。像這樣的約束可以幫助保持一個大型項目結束像糾結的意大利麪條。

還有其他的好處,但這些應該有助於說明爲什麼值得養成這種習慣。只要將一些東西寫入一個大包中,然後開始根據需要分解將某些類型,函數等移出到其他包中的文件即可;隨着時間的推移,「自然」邊界將開始變得更有意義。

相關問題