日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go 项目 cmd目录_Golang 项目布局浅析

發(fā)布時間:2025/3/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go 项目 cmd目录_Golang 项目布局浅析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

奇技 · 指南

Golang作為當下云開發(fā)中最為流行的語言之一,越來越受到廣大程序員的青睞。開發(fā)Golang項目經(jīng)常遇到的一個常見問題是如何組織項目結(jié)構(gòu)布局。今天作者從項目結(jié)構(gòu)以及對內(nèi)部、外部包的引用來講講布局問題,希望對大家有所幫助。

開始編碼之前,我們需要先明確一些問題:
  • 項目結(jié)構(gòu)如何反映代碼的引入方式?

  • 除代碼外,如何組織項目的命令行工具?

  • 如何靈活的在不同模塊間組織項目代碼?

  • 多個包如何在一個模塊中共存?

我們先明確一些名詞和概念:

Internal packages,內(nèi)部私有包,只能從其模塊中的其他包引入,不能被外部包引入。用戶可以使用 go get 安裝需要的外部包。

1

Helloworld

我們打開一個項目,項目路徑是模塊名。項目的 go.mod 文件包含以下行:

module github.com/qidian/modlibGo項目通常通過其GitHub路徑命名。Go還支持自定義名稱,本文暫不贅述,之后開新帖再說。我們可以暫時用`github.com/your-handle/your-project`或`your-project-domain.io`替換`github.com/qidian/modlib`。

模塊名稱非常重要,因為他是項目代碼中引入包名的基礎(chǔ):

2

項目布局

先來看一個項目 modlib 的目錄和文件布局:

├── LICENSE├── README.md├── config.go├── go.mod├── go.sum├── clientlib│ ├── lib.go│ └── lib_test.go├── cmd│ ├── modlib-client│ │ └── main.go│ └── modlib-server│ └── main.go├── internal│ └── auth│ ├── auth.go│ └── auth_test.go└── serverlib └── lib.go

讓我們從根目錄中的文件開始。

go.mod 是模塊定義文件。它包含上面顯示的模塊名稱,我的項目沒有依賴項。依賴項與項目布局設(shè)計無關(guān)。有需要的同學可以從 Golang 官方博客學習。go.sum 由 go tools 管理,其包含所有依賴項校驗值。

config.go,這是我們查看的第一個代碼文件,它包含一個簡單的?Config()函數(shù):

package modlibfunc Config() string {return "modlib config"}

第一行申明包名,由于該文件位于模塊的頂層,因此其程序包名稱即為模塊名稱。

關(guān)于如何引入?github.com/qidian/modlib?,我們來看一個例子:

package mainimport "fmt"import "github.com/qidian/modlib"func main() { fmt.Println(modlib.Config())}因此,如果您的模塊提供單個 package,或者您要從模塊的頂層軟件包中導出代碼,則將其所有代碼放在模塊的頂層目錄中,并命名該 package 作為模塊路徑的最后一部分(除非您使用更靈活的 vanity imports)。

3

引用外部包

clientlib / lib.go 是我們對 clientlib 模塊封裝的文件。文件名可以根據(jù)業(yè)務(wù)邏輯來命名:

package clientlibfunc Hello() string {return "clientlib hello"}

我們再來看下面這個例子,通過 github.com/qidian/modlib/clientlib 導入 clientlib:

package mainimport "fmt"import "github.com/qidian/modlib"import "github.com/qidian/modlib/clientlib"func main() { fmt.Println(modlib.Config()) fmt.Println(clientlib.Hello())}serverlib目錄包含了另一個用戶可以引入的package。這里展示了多個程序包如何在代碼結(jié)構(gòu)中并存。

關(guān)于包嵌套,它可以根據(jù)需要增加目錄層級。我們可見的? package 名稱由模塊根目錄的相對路徑確定。例如,如果我們有一個 `clientlib/tokens` 的子目錄 ,并在tokens包中包含一些代碼,則用戶將使用如下代碼引入該目錄。

import "github.com/qidian/modlib/clientlib/tokens“

對于一些模塊而言,一個頂級 package 就足夠業(yè)務(wù)開發(fā)了。在本例中沒有用戶可導入的 package 子目錄,但是所有代碼都在 modlib 的單個或多個 Go 文件中。

4

Commands

一些Go項目還需要制作可執(zhí)行程序,我們一般會再增加一個cmd目錄。

該目錄是項目所有命令行程序的常規(guī)位置。程序的命名方案通常為:

用戶可以使用go工具按如下方式安裝此類命令:$ go get github.com/qidian/modlib/cmd/cmd-name# Go downloads, builds and installs cmd-name into the default location.# The bin/ directory in the default location is often in $PATH, so we can#?just?invoke?cmd-name?now$ cmd-name ...

在modlib中,提供了兩個不同的命令行程序作為示例:modlib-client和modlib-server。在每個代碼中,代碼都在包main中;文件名為main.go。

這是我們在測試環(huán)境上運行的命令:$ go get github.com/qidian/modlib/cmd/modlib-client$ modlib-clientRunning clientConfig: modlib configclientlib hello$ go get github.com/qidian/modlib/cmd/modlib-server$ modlib-serverRunning serverConfig: modlib configAuth: thou art authorizedserverlib hello# Clean up...$ rm -f `which modlib-server` `which modlib-client`

我們來看看 modlib-serve.go 是如何從 modlib 中導入其他代碼的:

package mainimport (??"fmt""github.com/qidian/modlib""github.com/qidian/modlib/internal/auth""github.com/qidian/modlib/serverlib")func main() { fmt.Println("Running server") fmt.Println("Config:", modlib.Config()) fmt.Println("Auth:", auth.GetAuth()) fmt.Println(serverlib.Hello())}

Golang 里的絕對導入適用于引入package和二進制命令,這是 clientlib 中的代碼需要引入 modlib 時的例子:

github.com/eliben/modlib

4

私有包

另一個重要概念是私有包,也就是項目內(nèi)部使用的軟件包,并且我們不想導出給外部用戶。由于語義版本控制,這在Go模塊中尤其重要。您的項目在v1中導出的所有內(nèi)容都將成為公共API,并且必須遵守語義版本兼容性。

Go工具將內(nèi)部包識別為特殊路徑,只有同一模塊中的軟件包可以引入它。如果我們嘗試在外部模塊代碼中引用,則會拋錯:

use of internal package github.com/eliben/modlib/internal/auth not allowed

在本文樣例中,internal中只有一個package。而在實際的工程項目里通常會有一堆完整的package目錄樹。

將內(nèi)部API重構(gòu)并將其導出給其他同學很容易,但是使用外部API并取消導出會很麻煩。所以我在開發(fā)時會盡可能地將模塊需要的私有包和代碼放入內(nèi)部包中。最后再舉個例子,如果一個網(wǎng)站項目 repo 中,我們將代碼安排在 internal/website中。用于項目的內(nèi)部工具和腳本也是如此。這樣一來項目的根目錄是最清晰并且對開發(fā)者來說更友好。理想情況下,開發(fā)者通過項目代碼布局就可以大致了解他們想了解的東西所在位置,因此將一些代碼放在內(nèi)部會很有意義。

相關(guān)文章

  • https://blog.golang.org/v2-go-modules

  • https://blog.golang.org/module-compatibility

往期精彩回顧

TensorNet——基于TensorFlow的大規(guī)模稀疏特征模型分布式訓練框架

一種通過云配置處理應用權(quán)限彈框的方案

360Stack裸金屬服務(wù)器部署實踐

360技術(shù)公眾號

技術(shù)干貨|一手資訊|精彩活動

掃碼關(guān)注我們

總結(jié)

以上是生活随笔為你收集整理的go 项目 cmd目录_Golang 项目布局浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。