從一知半解到略懂Go modules
文章推薦指數: 80 %
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搭配正規表示式擷取字串
延伸文章資訊
- 1深入Go Module之go.mod文件解析 - 鸟窝
Go module就是一组统一打版和发布的package的集合,在根文件下有go.mod文件定义module path和依赖库的版本,package以子文件夹的形式存在module中,对 ...
- 2Tutorial: Create a Go module - go.dev
Start by creating a Go module. In a module, you collect one or more related packages for a discre...
- 3[Day05] golang package & golang module - iT 邦幫忙
本文同步發表於: Sponge Records. 本文將會介紹什麼是golang package、golang module 在開發的時候,很難所有功能都自己刻,而且也要避免掉重複造輪的問題,因...
- 4Go Module與Go get 常用參數說明 - 關於網路那些事...
不支持module,會從GOPATH 或vendor 來尋找。如果不是在GOPATH 執行go mod init 則會報錯。 GO111MODULE=auto, 會檢查當前目錄是否啟用go.mo...
- 5【Golang】還在把library 放在專案裡?該跟上使用Go Module ...
Golang 在1.11 開始就推出了Go Module,如果你才剛開始使用Golang,建議直接使用Go Module,才不會被GOPATH 搞的滿頭包。本篇先以初始專案視角介紹,如果要從舊的...