從一知半解到略懂Go modules

文章推薦指數: 80 %
投票人數:10人

Go 1.11 之後提供go modules 讓我們可以不需要把專案程式碼放在 $GOPATH/src ... go.mod 用來紀錄Go module 的名稱與所使用的Go 版本,以及相依的Go ... Energyandpersistenceconquerallthings. 211 文章 16 分類 161 標籤 週一,11月022020 從一知半解到略懂Gomodules AmoChen go 一直以來沒有好好去詳讀gomodules的文件,所以都覺得對gomodules只是一知半解。

這次花了些時間看了關於gomodules的相關文件,並實際寫個小範例體驗,最後整理成本文分享。

本文環境 macOS10.15 Go1.13 引言先前Golang-從HelloWorld認識GOPATH一文中,我們認識了GOPATH的作用,然而GOPATH會讓我們的專案程式碼與其他相依的程式碼一起存在$GOPATH/src資料夾底下,相較於其他程式語言而言,使用上較不直覺,也欠缺相依性管理的功能。

Go1.11之後提供gomodules讓我們可以不需要把專案程式碼放在$GOPATH/src中開發,此外還能管理套件相依性,相當便利。

Gomodules初體驗首先設置好GOPATH之後,先在$GOPATH/src之外,新增1個資料夾存放專案程式: $exportGOPATH=/path/to/goworkspace $mkdirmyproject $cdmyproject接著用以下指令新增Gomodule: $gomodinitgithub.com/username/myprojectp.s.github.com/username/myproject可以換成任意字串,因爲個人希望將Gomodule放置於GitHub,因此將模組名稱設定為github.com/username/myproject 上述指令成功後,將會看到資料夾內出現1個檔案go.mod: modulegithub.com/username/myproject go1.13go.mod用來紀錄Gomodule的名稱與所使用的Go版本,以及相依的Gomodules,該檔案是Gomodule必備的檔案 再來新增2個資料夾,以及2個.go檔,建立範例所需要的環境: $mkdirgreetingcli $touchgreeting/greeting.gocli/say.go進行至此,myproject的資料夾結構應如下所示: . ├──cli │└──say.go ├──go.mod └──greeting └──greeting.go最後將greeting.go與say.go填入以下程式碼。

greeting.go是1個簡單的package,用以列印所傳入的字串;而say.go則是用以呼叫greeting.gopackage所提供的函示。

greeting.go的內容: packagegreeting import"fmt" funcSay(sstring){ fmt.Println(s) }say.go的內容: packagemain import"github.com/username/myproject/greeting" funcmain(){ greeting.Say("Hello") }最後,試著編譯一次,正常的話不會有任何錯誤訊息: $gobuild./...至此,我們已經利用gomodules成功地將Go專案移出$GOPATH/src囉! p.s.如果把go.mod刪除的話,就會發現類似以下的錯誤,這是由於go找不到go.mod因此轉而至$GOPATH尋找相關的gopackage的緣故: cli/say.go:3:8:cannotfindpackage"github.com/username/myproject/greeting"inanyof: /usr/local/go/src/github.com/username/myproject/greeting(from$GOROOT) $GOPATH/src/github.com/username/myproject/greeting(from$GOPATH)使用gomodules進行套件相依性管理Gomodules提供的另一個方便的功能則是套件相依性管理,接下來實際透過以下指令安裝套件試試: $gogetgithub.com/fatih/color安裝成功之後,可以再看一次go.mod,會發現多了1行requiregithub.com/fatih/colorv1.9.0: modulegithub.com/username/myproject go1.13 requiregithub.com/fatih/colorv1.9.0requiregithub.com/fatih/colorv1.9.0目前的Go專案需要v1.9.0版的github.com/fatih/color。

p.s.gomodules使用的版本號規則是semanticversion,有興趣的話,可以詳閱該文件 有時候我們可能會需要使用指定版本的package,這時候可以在package尾端加上@版本號,例如以下指定使用v1.8.0的github.com/fatih/color: $gogetgithub.com/fatih/[email protected]安裝完成後,再看一次go.mod會發現除了github.com/fatih/color版本變為v1.8.0之外,又多了2個//indirect的gopackages: modulegithub.com/username/myproject go1.13 require( github.com/fatih/colorv1.8.0 github.com/mattn/go-colorablev0.1.4//indirect github.com/mattn/go-isattyv0.0.11//indirect )//indirect指的是被相依的套件所使用的packages: Theindirectcommentindicatesadependencyisnotuseddirectlybythismodule,onlyindirectlybyothermoduledependencies. 另一種常見情況是我們可能會指定package到某個commitid,這時候就能夠使用pseudo-version,例如v0.0.0-20170915032832-14c0d48ead0c就是1個指定使用20170915032832-14c0d48ead0ccommit的pseudo-version. pseudo-version,whichisthegocommand’sversionsyntaxforaspecificuntaggedcommit. 接著,可以再把greeting.go與say.go改為以下形式,使用剛剛所安裝的package。

greeting.go的內容: packagegreeting import"fmt" import"github.com/fatih/color" funcSay(sstring){ fmt.Println(s) } funcSayWithColor(sstring){ color.Red(s) }say.go的內容: packagemain import"github.com/username/myproject/greeting" funcmain(){ greeting.Say("Hello") greeting.SayWithColor("World") }go.mod的replace語法go.mod還提供replace語法,能夠讓我們取代指定的套件,例如replacegithub.com/fatih/color=>../mycolor代表至../mycolor資料夾中載入github.com/fatih/colorpackage,例如以下的go.mod: modulegithub.com/username/myproject go1.13 require( github.com/fatih/colorv1.8.0 github.com/mattn/go-colorablev0.1.4//indirect github.com/mattn/go-isattyv0.0.11//indirect ) replacegithub.com/fatih/color=>../mycolor除了直接編輯go.mod之外,也可以用以下指令: $gomodedit-replacegithub.com/fatih/color=../mycolorreplace能夠讓我們輕易地將特定package重新定位到特定路徑下,除了能夠方便修改之外,也能夠讓我們更輕鬆地測試package不同版本的行為等等,值得注意的是特定路徑下的package也必須有go.mod檔才行 ../mycolor是代表在go.mod檔案的所在目錄的上一層,所以可以先切換至上一層目錄後,再次下載https://github.com/fatih/color試試: $cd../ $gitclonehttps://github.com/fatih/colormycolor此時的資料夾結構應該會類似以下: . ├──mycolor │├──LICENSE.md │├──README.md │├──color.go │├──color_test.go │├──doc.go │├──go.mod │├──go.sum │└──vendor ├──myproject │├──cli │├──go.mod │├──go.sum │└──greeting └──pkg接著回到myproject試著編譯看看,正常的話就不會出現任何訊息: $cdmyproject $gobuild./...如此代表成功體驗replace的功用了! 結語以上就是關於gomodules的一些解說與用法,還有很多細節可以詳閱官方文件,相信大家閱讀之後都可以有不少收獲! Happycoding! Referenceshttps://blog.golang.org/using-go-modules https://golang.org/ref/mod Python模組介紹-contextlib Python好用模組-pathlib ©2021PoweredbyHexo    |    隱私權政策 目錄 1.本文環境2.引言3.Gomodules初體驗4.使用gomodules進行套件相依性管理5.go.mod的replace語法6.結語7.References 目錄 1.本文環境2.引言3.Gomodules初體驗4.使用gomodules進行套件相依性管理5.go.mod的replace語法6.結語7.References 分類 Android6CSS1Django4Docker2Golang8GoogleSheets7Javascript1Mathematics1Mysql1Productivity11Python108R1React4Security1VSCode1Vim5 最新文章 實戰Python效能分析-從cProfile到py-spy 實戰Fil改善Python記憶體用量 用Pythonresource模組找出尖峰記憶體用量 Dockermultistagebuilds教學 用grep搭配正規表示式擷取字串



請為這篇文章評分?