Go模塊布局管理文檔翻譯理解
Organizing a Go module
原文:https://go.dev/doc/modules/layout
新的Go開發(fā)者經(jīng)常會(huì)提出一個(gè)問題:如何組織一個(gè)Go項(xiàng)目?這個(gè)問題主要指文件和文件夾布局方面。
本文的目標(biāo)是提供一些有助于回答這個(gè)問題的準(zhǔn)則。為了充分利用本文,請(qǐng)確保你熟悉Go模塊的基本概念,你可以閱讀下面兩個(gè)文檔:
- the tutorial : https://go.dev/doc/tutorial/create-module
- managing module source : https://go.dev/doc/modules/managing-source
Go項(xiàng)目可以包括包、命令行程序或者是這兩者的組合,本文按項(xiàng)目類型來組織。
Basic package
一個(gè)基本的Go包可以把所有代碼放在項(xiàng)目的根目錄中。該項(xiàng)目由單個(gè)包,即單個(gè)模塊組成。
對(duì)于最簡(jiǎn)單的包,只需要一個(gè)Go文件(不包含test文件),項(xiàng)目結(jié)構(gòu)是:
project-root-directory/ go.mod modname.go modname_test.go
包名與模塊名的最后一個(gè)路徑組件匹配,modname中的包聲明代碼如下:
(譯者注:實(shí)際上不同名也可以,但易用性很差,不建議這樣做,或者至少要在文檔中明確說明)
package modname // ... package code here
如果這個(gè)目錄上傳到GitHub存儲(chǔ)庫(kù)github.com/someuser/modname
,那么go.mod文件中的模塊行應(yīng)表述如下:
module github.com/someuser/modname
用戶若需要依賴這個(gè)包,可以按如下方法導(dǎo)入:
import "github.com/someuser/modname"
一個(gè)Go包可以被分隔為多個(gè)文件,所有文件處于同一目錄中,如:
project-root-directory/ go.mod modname.go modname_test.go auth.go auth_test.go hash.go hash_test.go
目錄中的所有文件都需要聲明包名modname。
Basic command
基本的可執(zhí)行程序(或命令行工具)是根據(jù)其復(fù)雜程度和代碼量大小來構(gòu)建的。
最簡(jiǎn)單的程序由一個(gè)定義了main函數(shù)的Go文件組成。
更大的程序可以將代碼分隔到多個(gè)文件中,并且所有文件都聲明包名main,如:
project-root-directory/ go.mod auth.go auth_test.go client.go main.go
這里的main.go文件包含main函數(shù),但這只是一種慣例。“主”文件也可以被叫做modname.go(以匹配包名)或其他任何名字。
如果這個(gè)目錄上傳到GitHub存儲(chǔ)庫(kù)github.com/someuser/modname
,那么go.mod文件中的模塊行影表述如下:
module github.com/someuser/modname
用戶若需要使用這個(gè)程序,可以按如下方法安裝:
$ go install github.com/someuser/modname@latest
Package or command with supporting packages
更大的包或命令行工具(command)受益于將一部分功能分隔到支援包中。
(譯者注:這段翻譯可讀性有點(diǎn)差,我個(gè)人覺得主要是原文表意就不太明確,主要想表達(dá)的應(yīng)該是更大的包或command基于可讀性和功能隔離等需求,應(yīng)該將部分功能分隔到supporting packages中)
起初,我們建議將這些包放入internal目錄中,這樣可以防止外部依賴或避免不需要的代碼暴露。由于外部程序不能導(dǎo)入我們internal目錄中的代碼,我們可以任意重構(gòu)或者改變代碼,而不會(huì)影響外部用戶。
這樣的包的項(xiàng)目結(jié)構(gòu)如下:
project-root-directory/ internal/ auth/ auth.go auth_test.go hash/ hash.go hash_test.go go.mod modname.go modname_test.go
modname.go文件聲明包名modname,auth.go文件聲明包名auth,依此類推。
modname.go可以按如下方法導(dǎo)入auth包:
import "github.com/someuser/modname/internal/auth"
使用internal目錄保存支援包的命令行工具的布局類似,區(qū)別僅為,根目錄中的文件(都)應(yīng)該聲明包名main。
Multiple packages
一個(gè)模塊可以由多個(gè)可導(dǎo)入的包組成,每個(gè)包都有自己的目錄,并可以分層構(gòu)建,如下:
project-root-directory/ go.mod modname.go modname_test.go auth/ auth.go auth_test.go token/ token.go token_test.go hash/ hash.go internal/ trace/ trace.go
提醒一下,我們假設(shè)go.mod中的模塊行如下:
import "github.com/someuser/modname"
子包可以被其他用戶用如下方法導(dǎo)入:
import "github.com/someuser/modname/auth" import "github.com/someuser/modname/auth/token" import "github.com/someuser/modname/hash"
而放在internal/trace目錄中的trace包則不能被外部模塊導(dǎo)入。
建議盡可能的將包保存在internal目錄下。
(譯者注:這個(gè)說法原文并沒有給出明確的解釋,理由和是否遵循這一建議大家可以各自發(fā)揮)
Multiple commands
一個(gè)項(xiàng)目中的多個(gè)可執(zhí)行程序通常有不同的目錄,如下:
project-root-directory/ go.mod internal/ ... shared internal packages prog1/ main.go prog2/ main.go
在各自的目錄中,程序的Go文件聲明包名main。頂級(jí)的internal目錄可以存放多個(gè)程序共用的包。
用戶可以按如下方法安裝這些程序:
$ go install github.com/someuser/modname/prog1@latest $ go install github.com/someuser/modname/prog2@latest
一個(gè)常見的約定是將同一個(gè)倉(cāng)庫(kù)的命令行程序都放入cmd目錄。
在一個(gè)只由命令行程序構(gòu)成的項(xiàng)目中,這不是嚴(yán)格必須的。
但在由可導(dǎo)出包和命令行程序構(gòu)成的混合倉(cāng)庫(kù)中,這種用法是非常有效的,接下來便會(huì)討論。
Packages and commands in the same repository
有時(shí)候一個(gè)倉(cāng)庫(kù)既提供可導(dǎo)出包,也提供具有相關(guān)功能的可安裝命令行程序。如下:
project-root-directory/ go.mod modname.go modname_test.go auth/ auth.go auth_test.go internal/ ... internal packages cmd/ prog1/ main.go prog2/ main.go
假設(shè)這個(gè)模塊被命名為github.com/someuser/modname
。
用戶可以按照下面的方法導(dǎo)入模塊,或者安裝命令:
Go文件中:
import "github.com/someuser/modname" import "github.com/someuser/modname/auth"
命令行中:
$ go install github.com/someuser/modname/cmd/prog1@latest $ go install github.com/someuser/modname/cmd/prog2@latest
Server project
Go是實(shí)現(xiàn)服務(wù)器的常用語(yǔ)言。
考慮到服務(wù)器的種類繁多,比如協(xié)議(REST、gRPC等)、部署、前端、容器化、腳本等等,這類項(xiàng)目的目錄結(jié)構(gòu)存在很大差異。
我們重點(diǎn)介紹其中Go語(yǔ)言編寫的項(xiàng)目部分。
由于服務(wù)器通常是一個(gè)(或多個(gè))自包含的二進(jìn)制文件,因此服務(wù)器程序通常不需要對(duì)外導(dǎo)出包,所以建議將提供服務(wù)器邏輯的Go模塊放入internal目錄。
另外,由于程序可以包含其他非Go文件,所以將所有Go命令行程序放在cmd目錄下是個(gè)好主意。
如下:
project-root-directory/ go.mod internal/ auth/ ... metrics/ ... model/ ... cmd/ api-server/ main.go metrics-analyzer/ main.go ... ... the project's other directories with non-Go code
考慮到服務(wù)器倉(cāng)庫(kù)可能產(chǎn)生一些對(duì)外部程序也十分有用的包,最好的方法是將這些包剝離出來形成單獨(dú)的模塊。
(譯者注:這里并沒有詳細(xì)說明建議剝離出的包是當(dāng)前項(xiàng)目導(dǎo)出包還是拆分成單獨(dú)的項(xiàng)目,大家各自發(fā)揮)
譯者結(jié)語(yǔ)
前面的內(nèi)容基本就是原文的翻譯了。
簡(jiǎn)單總結(jié)如下:
Go的包隔離層級(jí)為:目錄。同一個(gè)目錄下的Go文件都聲明為同一個(gè)包。
Go語(yǔ)言的包管理遵循下面的幾條原則:
- 簡(jiǎn)便。最簡(jiǎn)便的包和程序不需要復(fù)雜的布局。
- 私用。盡量使用internal目錄隔離不需要對(duì)外導(dǎo)出的功能。internal目錄約束在1.4版本中引入。
- 隔離。隔離保證復(fù)雜功能布局下的可讀性,如cmd目錄。
- 拆包。如果一個(gè)模塊的功能本身在一定程度上是完備的,可以考慮拆分。
以上就是Go模塊布局管理文檔翻譯理解的詳細(xì)內(nèi)容,更多關(guān)于Go模塊布局管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang自動(dòng)追蹤GitHub上熱門AI項(xiàng)目
這篇文章主要為大家介紹了Golang自動(dòng)追蹤GitHub上熱門AI項(xiàng)目,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12使用golang引入外部包的三種方式:go get, go module, ve
這篇文章主要介紹了使用golang引入外部包的三種方式:go get, go module, vendor目錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Go語(yǔ)言中g(shù)oroutine和WaitGroup的使用示例詳解
goroutine 是Go中一個(gè)輕量級(jí)的線程, 只需要一個(gè)go關(guān)鍵字就可以創(chuàng)建一個(gè)goroutine,這篇文章主要介紹了Go語(yǔ)言中g(shù)oroutine和WaitGroup的使用,需要的朋友可以參考下2023-03-03Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法
在cmd下運(yùn)行g(shù)o程序或者是GOLAND的Terminal下運(yùn)行g(shù)o程序會(huì)出現(xiàn)中文亂碼的情況。本文就詳細(xì)的介紹下解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2021-12-12go local history本地歷史恢復(fù)代碼神器
這篇文章主要為大家介紹了go local history本地歷史恢復(fù)代碼神器的使用功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01golang獲取變量或?qū)ο箢愋偷膸追N方式總結(jié)
在golang中并沒有提供內(nèi)置函數(shù)來獲取變量的類型,但是通過一定的方式也可以獲取,下面這篇文章主要給大家介紹了關(guān)于golang獲取變量或?qū)ο箢愋偷膸追N方式,需要的朋友可以參考下2022-12-12