【Go基礎(chǔ)】GOPATH犬性、GOROOT瞻离、GOMOD

我們可以輸入go env查看我們的go環(huán)境變量

GOPATH="/Users/inf/go"
GOROOT="/usr/local/go"
GO111MODULE="auto"

GOPATH

GOPATH 是 Go語(yǔ)言中使用的一個(gè)環(huán)境變量,它使用絕對(duì)路徑提供項(xiàng)目的工作目錄仔夺。

  • 工作目錄:一個(gè)工程開(kāi)發(fā)的相對(duì)參考目錄琐脏。工作區(qū)的概念與工作目錄的概念也是類(lèi)似的。如果不使用工作目錄的概念缸兔,在多人開(kāi)發(fā)時(shí)日裙,每個(gè)人有一套自己的目錄結(jié)構(gòu),讀取配置文件的位置不統(tǒng)一惰蜜,輸出的二進(jìn)制運(yùn)行文件也不統(tǒng)一昂拂,這樣會(huì)導(dǎo)致開(kāi)發(fā)的標(biāo)準(zhǔn)不統(tǒng)一,影響開(kāi)發(fā)效率抛猖。

命令行輸出我們可以看到go的工作目錄GOPATH默認(rèn)為/Users/xxx/go/

使用GOPATH的工程結(jié)構(gòu)

在 GOPATH 指定的工作目錄下格侯,代碼總是會(huì)保存在 $GOPATH/src 目錄下。在工程經(jīng)過(guò) go build财著、go installgo get 等指令后联四,會(huì)將產(chǎn)生的二進(jìn)制可執(zhí)行文件放在 $GOPATH/bin目錄下,生成的中間緩存文件會(huì)被保存在 $GOPATH/pkg 下撑教。

如果需要將整個(gè)源碼添加到版本管理工具(Version Control System朝墩,VCS)中時(shí),只需要添加 $GOPATH/src 目錄的源碼即可伟姐。bin 和 pkg 目錄的內(nèi)容都可以由 src 目錄生成收苏。

設(shè)置和使用GOPATH

我們可以使用命令

export GOPATH=`pwd`

選擇一個(gè)目錄亿卤,在目錄中的命令行中執(zhí)行下面的指令:設(shè)置當(dāng)前目錄為GOPATH

該指令中的 pwd 將輸出當(dāng)前的目錄,使用反引號(hào)`將 pwd 指令括起來(lái)表示命令行替換鹿霸,也就是說(shuō)排吴,使用 `pwd` 將獲得 pwd 返回的當(dāng)前目錄的值。例如懦鼠,假設(shè)你的當(dāng)前目錄是“/Users/xxx/go”钻哩,那么使用pwd將獲得返回值“/Users/xxx/go”。

使用 export 指令可以將當(dāng)前目錄的值設(shè)置到環(huán)境變量 GOPATH中葛闷。

網(wǎng)上建議大家無(wú)論是使用命令行或者使用集成開(kāi)發(fā)環(huán)境編譯 Go 源碼時(shí)憋槐,GOPATH 跟隨項(xiàng)目設(shè)定。在 Jetbrains 公司的 GoLand 集成開(kāi)發(fā)環(huán)境(IDE)中的 GOPATH 設(shè)置分為全局 GOPATH 和項(xiàng)目 GOPATH淑趾,如下圖所示


Global GOPATH 代表全局 GOPATH,一般來(lái)源于系統(tǒng)環(huán)境變量中的 GOPATH忧陪;Project GOPATH 代表項(xiàng)目所使用的 GOPATH扣泊,該設(shè)置會(huì)被保存在工作目錄的 .idea 目錄下,不會(huì)被設(shè)置到環(huán)境變量的 GOPATH 中嘶摊,但會(huì)在編譯時(shí)使用到這個(gè)目錄延蟹。建議在開(kāi)發(fā)時(shí)只填寫(xiě)項(xiàng)目 GOPATH,每一個(gè)項(xiàng)目盡量只設(shè)置一個(gè) GOPATH叶堆,不使用多個(gè) GOPATH 和全局的 GOPATH阱飘。

GOROOT

GOROOT就是我們Go語(yǔ)言的安裝路徑。我這里是/usr/local/go
打開(kāi)這個(gè)文件夾虱颗,同樣可以看到



src, bin, pkg三個(gè)文件夾沥匈,
標(biāo)準(zhǔn)的Go語(yǔ)言代碼庫(kù)中包含了大量的包,并且在安裝 Go 的時(shí)候多數(shù)會(huì)自動(dòng)安裝到系統(tǒng)中忘渔。我們可以在 $GOROOT/src/pkg 目錄中查看這些包高帖。當(dāng)我們 import內(nèi)置包的時(shí)候,并不需要額外安裝,當(dāng)程序運(yùn)行時(shí)畦粮,會(huì)先去GOROOT下找相應(yīng)的包來(lái)運(yùn)行散址。

我們可以在其他隨便一個(gè)文件夾下運(yùn)行下運(yùn)行mian.go
比如我新建了一個(gè)hello文件夾,


//main.go
package main
 ?
 import "fmt"
 ?
 func main() {
     fmt.Println("Hello World")
 }

會(huì)成功輸出Helo World宣赔,go run其實(shí)幫你將程序進(jìn)行編譯并生成可執(zhí)行文件预麸,而編譯文件和執(zhí)行文件實(shí)際上存在在一個(gè)暫存資料夾里面,當(dāng)運(yùn)行完這個(gè)程序就會(huì)自動(dòng)刪除儒将。該指令可以相乘類(lèi)似直譯的方式運(yùn)行吏祸,而不需要其他任何環(huán)境設(shè)定。
但如果
要引入hello.go椅棺,或者import 某個(gè)Github上的包犁罩,就會(huì)報(bào)錯(cuò)

import (
     "hello"
    )
 ?
 func main() {
    test1()
 }
// main.go:10:3: cannot find package "hello" in any of:
// /usr/local/go/src/hello (from $GOROOT)
// /Users/inf/go/src/hello (from $GOPATH)

1齐蔽、 當(dāng)執(zhí)行g(shù)olang程序,需要獲取import的包時(shí)床估,編譯器回先去GOROOT路徑下的src文件夾找有沒(méi)有我們?cè)诔绦蛑衖mport的包
2含滴、如果在GOROOT下沒(méi)有找到,就會(huì)去GOPATH下src下找這個(gè)包

所以只要GOROOT跟GOPATH下都沒(méi)找到包的話就會(huì)報(bào)錯(cuò)

go run, go build, go install

go run

go run 編譯并直接運(yùn)行程序丐巫,它會(huì)產(chǎn)生一個(gè)臨時(shí)文件(但不會(huì)生成 .exe 文件)谈况,直接在命令行輸出程序執(zhí)行結(jié)果,方便用戶調(diào)試递胧,產(chǎn)生執(zhí)行結(jié)果后就會(huì)自動(dòng)刪除碑韵。

go build

go build 用于測(cè)試編譯包,主要檢查是否會(huì)有編譯錯(cuò)誤缎脾,如果是一個(gè)可執(zhí)行文件的源碼(即是 main 包)祝闻,就會(huì)直接生成一個(gè)可執(zhí)行文件。

go build main.go

這樣會(huì)在當(dāng)前目錄下產(chǎn)生一個(gè)名稱(chēng)為mian的可執(zhí)行文件遗菠。也可以在build后面寫(xiě)專(zhuān)門(mén)的項(xiàng)目名稱(chēng)联喘,執(zhí)行該命令會(huì)自動(dòng)在當(dāng)前文件夾下找package為mian,并且有main function的go文件辙纬,再編譯成可執(zhí)行文件



也可以使用下面的命令指定build出來(lái)的可執(zhí)行文件放在哪里

go build -o bin/main src/demo/main.go

-o后面的第一個(gè)參數(shù)表示生產(chǎn)的可執(zhí)行文件的路徑以及名稱(chēng)豁遭,第二個(gè)參數(shù)代表要編譯的go文件的路徑。
按照慣例贺拣,GOPATH下bin文件夾存放build出來(lái)的可執(zhí)行文件蓖谢。

go build有個(gè)缺點(diǎn)就是每次編譯go文件比較沒(méi)有效率,當(dāng)項(xiàng)目架構(gòu)越來(lái)越大build的速度也越來(lái)越慢譬涡。

go install

go install 的作用有兩步:第一步是編譯導(dǎo)入的包文件闪幽,所有導(dǎo)入的包文件編譯完才會(huì)編譯主程序;第二步是將編譯后生成的可執(zhí)行文件放到 bin 目錄下($GOPATH/bin)昂儒,編譯后的包文件放到 pkg 目錄下($GOPATH/pkg)沟使。

go install 做兩件事情,

  • 將package編譯成.a file
  • 如果是main 包則編譯成可執(zhí)行文件

有了第一項(xiàng)功能渊跋,下次編譯時(shí)候就不會(huì)將包的程序碼重新編譯腊嗡,而是直接用編譯好的.a file。而.a file就位于GOPATH/pkg里面拾酝。

來(lái)看一個(gè)例子
GOPATH/src下新建兩個(gè)項(xiàng)目mypkg和mytest燕少,分別新建兩個(gè)go文件



mypkg.go

package mypkg
 ?
 import "fmt"
 ?
 func MyFunc() {
     fmt.Println("MyFunc")
 }

mytest.go

package main
 ?
 import (
     "mypkg"
 )
 ?
 func main() {
     mypkg.MyFunc()
 }

mytest.go中用了import了mypkg的包,而可以通過(guò)install指令將mypkg編譯成.a file

go install mypkg

可以發(fā)現(xiàn)在GOPATH/darwin_amd64/mypkg.a有該文件
darwin_amd64是由GOOS和GOARCH兩個(gè)環(huán)境變量所組合合成的

GOPATH缺點(diǎn)

當(dāng)我們的第三方包不是官方庫(kù)時(shí)都要放在GOPATH/src下才可以使用

我們通常使用go get指令來(lái)獲取第三方的包

go get github.com/gin-gonic/gin

go get 最長(zhǎng)用在當(dāng)我們想用別人公開(kāi)在github上的包蒿囤,可以幫我們從網(wǎng)上clone到GOPATH/src下客们。
是不是聽(tīng)起來(lái)很方便?會(huì)讓src下的項(xiàng)目變得很復(fù)雜,除了有自己的項(xiàng)目還有其他第三方庫(kù)的項(xiàng)目底挫。
在如果恒傻,我們的不同的項(xiàng)目采用的第三方庫(kù)是不同的版本怎么辦,go1.11以前是要設(shè)頂多組不同的GOPATH,雖然go社區(qū)也有開(kāi)發(fā)相對(duì)應(yīng)的包管理工具建邓,如Vender,Dep來(lái)結(jié)局該問(wèn)題盈厘,但它們都不是官方的。

GOMOD

Go Modules很像java的maven官边,將第三方的庫(kù)放在本地的空間沸手,但它不是自動(dòng)的下載包的
如下命令開(kāi)啟和關(guān)閉go mod

go env -w GO111MODULE=on 打開(kāi)

go env -w GO111MODULE=off 關(guān)閉

GO111MODULE有三個(gè)不同的值

  • auto

    • 當(dāng)存在 go.mod 文件時(shí)或處于 GOPATH 外, 其行為均會(huì)等同于于 GO111MODULE=on注簿。這意味著在 Go 1.13 及之后的版本你可以將所有的代碼倉(cāng)庫(kù)均存儲(chǔ)在 GOPATH 下契吉。
    • 當(dāng)處于 GOPATH 內(nèi)且沒(méi)有 go.mod 文件存在時(shí)其行為會(huì)等同于 GO111MODULE=off。
  • on
    即使項(xiàng)目在您的 GOPATH 中诡渴,GO111MODULE = on 仍將強(qiáng)制使用 Go 模塊捐晶。需要 go.mod 正常工作

  • off
    強(qiáng)制 Go 表現(xiàn)出 GOPATH 方式,即使在 GOPATH 之外妄辩。

下載下來(lái)的第三方庫(kù)在哪呢租悄?其實(shí)就在GOPATH/pkg/mod文件夾里面

接下來(lái)就是和maven很像的操作了
src下新建一個(gè)文件夾modtest
該文件夾下執(zhí)行

go mod init <module name>

<module name>可填可不填,不填的話就是采用項(xiàng)目文件夾的名稱(chēng),執(zhí)行后會(huì)出現(xiàn)一個(gè)go.mod的文件

module modtest

go 1.15

go.mod 提供了module, require、replace和exclude 四個(gè)命令

module 語(yǔ)句指定包的名字(路徑)
require 語(yǔ)句指定的依賴(lài)項(xiàng)模塊,默認(rèn)最新版恩袱,可以指定版本號(hào)
replace 語(yǔ)句可以替換依賴(lài)項(xiàng)模塊
exclude 語(yǔ)句可以忽略依賴(lài)項(xiàng)模塊
還有個(gè)go 命令定義go語(yǔ)言的版本

添加一個(gè),假設(shè)我要引入github.com/gin-gonic/gin v1.5.0這個(gè)包

module modtest

go 1.15

require github.com/gin-gonic/gin v1.5.0

在執(zhí)行

go mod download

會(huì)發(fā)現(xiàn)當(dāng)前文件夾下多了個(gè)go.sum的文件胶哲,該文件基本上用來(lái)記錄包版本的關(guān)系畔塔,不怎么需要理會(huì)。需要的包裝在GOPATH/pkg/mod文件夾下

之后運(yùn)行

go run main.go
GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

這個(gè)就是在local 8080 port開(kāi)啟一個(gè)web server~

當(dāng)然也可以不執(zhí)行g(shù)o mod download而直接運(yùn)行g(shù)o build或者go install也會(huì)自動(dòng)下載包
還有一種方法可以直接下載

使用go get命令

go get github.com/gin-gonic/gin@v1.6.3

或者require指定版本,執(zhí)行g(shù)o get指令鸯屿。和download是一樣的澈吨。
只要有開(kāi)啟gomod功能,go get就不會(huì)再src下放package寄摆,而是會(huì)放在/pkg/mod里面谅辣,并且mod會(huì)寫(xiě)好引入。也就不需要go mod download了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婶恼,一起剝皮案震驚了整個(gè)濱河市桑阶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌勾邦,老刑警劉巖蚣录,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異眷篇,居然都是意外死亡萎河,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)虐杯,“玉大人玛歌,你說(shuō)我怎么就攤上這事∏嬉” “怎么了支子?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)确憨。 經(jīng)常有香客問(wèn)我译荞,道長(zhǎng),這世上最難降的妖魔是什么休弃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任吞歼,我火速辦了婚禮,結(jié)果婚禮上塔猾,老公的妹妹穿的比我還像新娘篙骡。我一直安慰自己,他們只是感情好丈甸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布糯俗。 她就那樣靜靜地躺著,像睡著了一般睦擂。 火紅的嫁衣襯著肌膚如雪得湘。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天顿仇,我揣著相機(jī)與錄音淘正,去河邊找鬼。 笑死臼闻,一個(gè)胖子當(dāng)著我的面吹牛鸿吆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播述呐,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惩淳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了乓搬?” 一聲冷哼從身側(cè)響起思犁,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缤谎,沒(méi)想到半個(gè)月后抒倚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坷澡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年托呕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了含蓉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡项郊,死狀恐怖馅扣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情着降,我是刑警寧澤差油,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站任洞,受9級(jí)特大地震影響蓄喇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜交掏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一妆偏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盅弛,春花似錦钱骂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至讨盒,卻和暖如春解取,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背返顺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工肮蛹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人创南。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像省核,于是被迫代替她去往敵國(guó)和親稿辙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355