欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何在golang項(xiàng)目開(kāi)發(fā)中創(chuàng)建自己的Module

 更新時(shí)間:2023年09月24日 08:42:42   作者:demo007x  
既然我們使用了很多開(kāi)源的 module為我們的日常開(kāi)發(fā)提供了很多的便捷性,那我們?cè)撊绾螌?shí)現(xiàn)自己的 module 來(lái)提供給團(tuán)隊(duì)中使用,接下小編就給大家介紹一下在golang項(xiàng)目開(kāi)發(fā)如何創(chuàng)建自己的Module,需要的朋友可以參考下

為什么要?jiǎng)?chuàng)建一個(gè) Module?

我們?nèi)粘i_(kāi)發(fā)程序的時(shí)候都會(huì)引入第三方的 package,使用第三方的 package 的好處是我們可以快速的開(kāi)發(fā)我們的程序的功能,只需要專注我們自己項(xiàng)目的功能,而且第三方的 package 提供了強(qiáng)大的,豐富的功能模塊。比如 web 開(kāi)發(fā)框架 gin, echo,微服務(wù)開(kāi)發(fā)框架 go-micro、go-zero;權(quán)限控制:casbin,jwt: jwt-go, gorm:gorm, 存儲(chǔ):minio , 編寫(xiě)命令:cobra, 配置文件解析:viper,數(shù)據(jù)庫(kù):mysql 等等。這些包都是以 module 的形式提供的服務(wù)。

在自己的團(tuán)隊(duì)內(nèi)部同樣可以構(gòu)建自己的私有化的 module,工公司內(nèi)部的其他團(tuán)隊(duì)使用。比如我們公司有三個(gè)項(xiàng)目組,都有一些共同的項(xiàng)目。所以我們有公共的 module 放到 gitlab 上面提供不同團(tuán)隊(duì)的公共使用。同樣這樣也遵循了軟件設(shè)計(jì)的高內(nèi)聚低耦合的設(shè)計(jì)總則。將獨(dú)立的功能封轉(zhuǎn)為 module。

這樣做的好處是我們可以只實(shí)現(xiàn)一次共享使用,并不需要每個(gè)團(tuán)隊(duì)中都各自實(shí)現(xiàn),同樣也會(huì)帶啦有好多弊端。

如何實(shí)現(xiàn)我們自己的 Module?

既然我們使用了很多開(kāi)源的 module為我們的日常開(kāi)發(fā)提供了很多的便捷性,那我們?cè)撊绾螌?shí)現(xiàn)自己的 module 來(lái)提供給團(tuán)隊(duì)中使用,甚至可以開(kāi)放到 gitlab 上面提供給所有人使用(取之于開(kāi)源,饋與開(kāi)源)。

通過(guò)一下步驟來(lái)實(shí)現(xiàn)一個(gè)其他人可以使用的 module

  • 創(chuàng)建模塊:編寫(xiě)一個(gè)小模塊,其中包含可以從另一個(gè)模塊調(diào)用的函數(shù)。
  • 從另一個(gè)模塊調(diào)用您的代碼:導(dǎo)入并使用您的新模塊。
  • 返回并處理錯(cuò)誤: 添加簡(jiǎn)單的錯(cuò)誤處理。
  • 處理切片中的數(shù)據(jù)(Go 的動(dòng)態(tài)大小數(shù)組)。
  • 添加測(cè)試程序:使用 Go 的內(nèi)置單元測(cè)試功能來(lái)測(cè)試您的代碼。

創(chuàng)建一個(gè) module 目錄

首先創(chuàng)建一個(gè) Go 模塊。在模塊中,我們可以將一組有用的功能在一個(gè)或多個(gè)相關(guān)包中實(shí)現(xiàn)。

Go 代碼被分組為 package,package 又被分組為modulemodule 中需要指定運(yùn)行代碼所需的依賴項(xiàng),包括 Go 版本及其所需的其他模塊。

1、打開(kāi)控制臺(tái)并cd轉(zhuǎn)到工作目錄中,并創(chuàng)建目錄module/greetings

?mkdir module
?cd module/greetings/

2、go mod init命令初始化模塊 。

運(yùn)行go mod init命令,為其提供模塊路徑 - 此處使用example.com/greetings. 如果發(fā)布模塊,則這必須是 Go 工具可以下載您的模塊的路徑。那將是我們的代碼的存儲(chǔ)庫(kù)。

?$ go mod init example.com/greetings

go mod init命令創(chuàng)建一個(gè) go.mod 文件來(lái)跟蹤代碼的依賴項(xiàng)。當(dāng)我們添加依賴項(xiàng)時(shí),go.mod 文件將列出項(xiàng)目的代碼所依賴的版本。這可以保持構(gòu)建的可重復(fù)性,并讓我們可以直接控制要使用的模塊版本。

3、打開(kāi)編輯器在greetings創(chuàng)建目錄下創(chuàng)建 文件greetings.go并編寫(xiě)代碼:

?package greetings
??
?import (
?  "fmt"
?  "math/rand"
?)
?func Hello(name string) string {
?  return fmt.Sprintf("嗨,%v。歡迎!", name)
?}

該函數(shù)Hello 接受一個(gè)name類型為的參數(shù) string。該函數(shù)還返回一個(gè)string。在Go中,名稱以大寫(xiě)字母開(kāi)頭的函數(shù)可以被不在同一包中的函數(shù)調(diào)用。這在 Go 中稱為導(dǎo)出名稱。

從另一個(gè)模塊調(diào)用您的代碼

1、我們?cè)?greeting 的同級(jí)目錄創(chuàng)建 hello 目錄,作為調(diào)用者。

?~/Developer/module
?tree -d
?.
?├── greetings
?└── hello

2、打開(kāi)編輯器并創(chuàng)建文件 hello.go 文件。在 hello.go 文件中編寫(xiě)代碼:

?import (
?  "example.com/greetings"
?  "log"
?)
??
?func main() {
?  message := greetings.Hello("demo007")
? ?fmt.Println(message)
?}

在文件中聲明一個(gè)main包。在 Go 中,作為應(yīng)用程序執(zhí)行的代碼必須位于包中main。

導(dǎo)入兩個(gè)包:example.com/greetingsfmt。 導(dǎo)入 example.com/greetings可以訪問(wèn)該Hello 函數(shù)。還可以導(dǎo)入fmt, 以及處理輸入和輸出文本的函數(shù)(例如將文本打印到控制臺(tái))。greetings通過(guò)調(diào)用包的 函數(shù) 來(lái)獲取輸出信息。

3、編輯example.com/hello模塊以使用本地 example.com/greetings模塊。

example.com/greetings 對(duì)于生產(chǎn)使用, 可以從其存儲(chǔ)庫(kù)發(fā)布模塊,Go 工具可以在其中找到它并下載它。但是由于我們尚未發(fā)布該模塊,因此我們需要調(diào)整該模塊,以便它可以在本地文件系統(tǒng)上 example.com/hello找到代碼example.com/greetings

所以我們使用go mod edit命令編輯example.com/hello 模塊,將 Go 工具從其模塊路徑(模塊所在的位置)重定向到本地目錄(模塊所在的位置)。

在 hello 目錄中的命令提示符下,運(yùn)行以下命令:

?$ go mod edit -replace example.com/greetings=../greetings

該命令指定example.com/greetings應(yīng)替換為../greetings以便查找依賴項(xiàng)。運(yùn)行命令后,hello 目錄中的 go.mod 文件應(yīng)包含一條replace的指令。

?module example.com/hello
??
?go 1.20
??
?replace example.com/greetings => ../greetings
??
?require example.com/greetings v0.0.0-00010101000000-000000000000
??

然后我們?cè)诿钪?cd hello 的目錄中,并執(zhí)行命令 go mod tidy, 執(zhí)行完成后我們發(fā)現(xiàn)新增加一行 require example.com/greetings v0.0.0-00010101000000-000000000000 并制定了一個(gè)版本號(hào).

我們?cè)?hello 中執(zhí)行運(yùn)行命令查看:

?go run hello.go
?嗨,demo007。歡迎!

返回并處理錯(cuò)誤

處理錯(cuò)誤是可靠代碼的一個(gè)基本特征。下面我們將添加一些代碼以從 greetings 模塊返回錯(cuò)誤,然后在調(diào)用者中處理它。

在 greetings/greetings.go 中,修改代碼:

?package greetings
??
?import (
?  "errors"
?  "fmt"
?  "math/rand"
?)
??
?func Hello(name string) (string, error) {
?  // 如果沒(méi)有提供名稱,則返回帶有錯(cuò)誤消息的錯(cuò)誤。
?  if name == "" {
?    return name, errors.New("empty name")
?  }
??
?  // 使用隨機(jī)格式創(chuàng)建一條消息。
?  message := fmt.Sprintf("嗨,%v。歡迎!", name)
?  return message, nil
?}

我們修改了 Hello 函數(shù)添加了返回值 error,if 語(yǔ)句來(lái)檢測(cè)輸入的 name 是否是一個(gè)有效的值。如果為空則返回name 和 一個(gè) 錯(cuò)誤 errors.New("empty name")

hello/hello.go 文件中,處理函數(shù)現(xiàn)在返回的錯(cuò)誤 Hello以及非錯(cuò)誤值。

?package main
??
?import (
?  "example.com/greetings"
?  "fmt"
?  "log"
?)
??
?func main() {
?  message, err := greetings.Hello("demo007")
?  if err != nil {
?    log.Fatal(err)
?  }
?  fmt.Println(message)

使用標(biāo)準(zhǔn)庫(kù)中的函數(shù)log package輸出錯(cuò)誤信息。如果出現(xiàn)錯(cuò)誤,可以使用 log包的Fatal來(lái)打印錯(cuò)誤并停止程序。

在目錄中的命令行中hello,運(yùn)行 hello.go 以確認(rèn)代碼有效

?go run hello.go
?Great to see you, demo007!

處理切片中的數(shù)據(jù)

我們將使用 Go 切片。切片類似于數(shù)組,只不過(guò)它的大小會(huì)隨著添加和刪除項(xiàng)目而動(dòng)態(tài)變化。切片是 Go 最有用的類型之一。

我們將添加一個(gè)小切片來(lái)包含三條問(wèn)候消息,然后讓代碼隨機(jī)返回其中一條消息。

greetings/greetings.go 中,我們修改代碼,如下所示。

?package greetings
??
?import (
?  "errors"
?  "fmt"
?  "math/rand"
?)
??
?func Hello(name string) (string, error) {
?  // 如果沒(méi)有提供名稱,則返回帶有錯(cuò)誤消息的錯(cuò)誤。
?  if name == "" {
?    return name, errors.New("empty name")
?  }
??
?  // 使用隨機(jī)格式創(chuàng)建一條消息。
?  message := fmt.Sprintf(randomFormat(), name)
?  return message, nil
?}
??
?func randomFormat() string {
?  formats := []string{
?    "Hi, %v. Welcome!",
?    "Great to see you, %v!",
?    "Hail, %v! Well met!",
?  }
?  return formats[rand.Intn(len(formats))]
?}

1、添加一個(gè)randomFormat函數(shù),返回隨機(jī)選擇的問(wèn)候消息格式。 randomFormat以小寫(xiě)字母開(kāi)頭,使其只能被其自己的包中的代碼訪問(wèn)(換句話說(shuō),它不會(huì)被導(dǎo)出)。

2、在 中randomFormat,聲明formats具有三種消息格式的切片。聲明切片時(shí),您可以在括號(hào)中省略其大小,如下所示:[]string。這告訴 Go 切片底層數(shù)組的大小可以動(dòng)態(tài)更改。

3、使用該 math/rand 包生成一個(gè)隨機(jī)數(shù),用于從切片中選擇一個(gè)項(xiàng)目。

4、在 中Hello,調(diào)用該randomFormat函數(shù)來(lái)獲取您將返回的消息的格式,然后 name一起使用該格式和值來(lái)創(chuàng)建消息。

5、像以前一樣返回消息以及錯(cuò)誤

hello/hello.go 中,我們修改代碼,如下所示:

?package main
??
?import (
?  "example.com/greetings"
?  "fmt"
?  "log"
?)
??
?func main() {
?  message, err := greetings.Hello("demo007x")
?  // 如果返回了錯(cuò)誤,請(qǐng)將其打印到控制臺(tái)并退出程序。
?  if err != nil {
?    log.Fatal(err)
?  }
?  //如果沒(méi)有返回錯(cuò)誤,請(qǐng)將返回的消息打印到控制臺(tái)。
?  fmt.Println(message)
?}
??

我們運(yùn)行代碼看看輸出的內(nèi)容:

 go run hello.go
 Hail, demo007x! Well met!
 ?
 go run hello.go
 Great to see you, demo007x!
 ?
 go run hello.go
 Hi, demo007x. Welcome!

測(cè)試 module

以上我們編寫(xiě)了基本的或者說(shuō)是最簡(jiǎn)單的 golang module 的程序項(xiàng)目,如何確保我們的程序是無(wú)錯(cuò)誤的或者是沒(méi)有 bug 的?最好的辦法就是添加 測(cè)試程序。

在開(kāi)發(fā)過(guò)程中測(cè)試代碼可能會(huì)暴露出在您進(jìn)行更改時(shí)出現(xiàn)的錯(cuò)誤。

Go 對(duì)單元測(cè)試的內(nèi)置支持使我們可以更輕松地進(jìn)行測(cè)試。具體來(lái)說(shuō),使用命名約定、Go 的testing包和go test命令,可以快速編寫(xiě)和執(zhí)行測(cè)試。

  • 在greetings目錄中,創(chuàng)建一個(gè)名為greetings_test.go的文件。

    以 _test.go 結(jié)尾的文件名告訴go test命令該文件包含測(cè)試函數(shù)。

  • 在greetings_test.go中,編寫(xiě)以下代碼并保存文件:

?package greetings
??
?import (
?  "regexp"
?  "testing"
?)
??
?// TestHelloName 調(diào)用 greetings.Hello 并傳入一個(gè)名稱,檢查返回值是否有效。
?func TestHelloName(t *testing.T) {
?  name := "Gladys"
?  want := regexp.MustCompile(`\b` + name + `\b`)
?  msg, err := Hello("Gladys")
?  if !want.MatchString(msg) || err != nil {
?    t.Fatalf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want)
?  }
?}
??
?// TestHelloEmpty 調(diào)用 greetings.Hello 并傳入空字符串, 檢查是否出現(xiàn)錯(cuò)誤。
?func TestHelloEmpty(t *testing.T) {
?  msg, err := Hello("")
?  if msg != "" || err == nil {
?    t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err)
?  }
?}
  • 創(chuàng)建兩個(gè)測(cè)試函數(shù)來(lái)測(cè)試該greetings.Hello 函數(shù)。測(cè)試函數(shù)名稱的形式為,其中Name表示有關(guān)特定測(cè)試的信息。此外,測(cè)試函數(shù)將指向包的指針作為參數(shù)。可以使用此參數(shù)的方法來(lái)報(bào)告和記錄測(cè)試。

  • 兩個(gè)測(cè)試:

    • TestHelloName調(diào)用該Hello函數(shù),傳遞一個(gè)name值,該函數(shù)應(yīng)該能夠返回有效的響應(yīng)消息。如果調(diào)用返回錯(cuò)誤或意外響應(yīng)消息(不包含您傳入的名稱),則可以使用參數(shù)t的方法將消息打印到控制臺(tái)并結(jié)束執(zhí)行Fatalf
    • TestHelloEmpty Hello使用空字符串調(diào)用該函數(shù)。此測(cè)試目的在確認(rèn)錯(cuò)誤處理是否有效。如果調(diào)用返回非空字符串或沒(méi)有錯(cuò)誤,則可以使用t參數(shù)的Fatalf 方法將消息打印到控制臺(tái)并結(jié)束執(zhí)行。
  • 在greetings目錄下的命令行中,運(yùn)行命令 go test 執(zhí)行測(cè)試。

?go test -v
?=== RUN ? TestHelloName
?--- PASS: TestHelloName (0.00s)
?=== RUN ? TestHelloEmpty
?--- PASS: TestHelloEmpty (0.00s)
?PASS
?ok    example.com/greetings 0.007s
  • 通過(guò)測(cè)試輸出的結(jié)果可以看到我們的程序全部都通過(guò)了測(cè)試。

發(fā)布module

以上我們編寫(xiě)了我們的第一個(gè) go module, 并且編寫(xiě)了對(duì)應(yīng)函數(shù)的測(cè)試程序,然后我們可以將我們的 module 程序提交到 github等系統(tǒng)。其他人就可以通過(guò)執(zhí)行命令 go get example.com/greetingsgreeting 包安裝到自己的項(xiàng)目中。

總結(jié):

golang module 給我們提供了靈活的本地開(kāi)發(fā)并測(cè)試 module 的機(jī)制。我們通過(guò)修改 go.mod 文件,通過(guò)指令 replace example.com/greetings => ../greetings 來(lái)實(shí)現(xiàn)本地 module 的開(kāi)發(fā)和測(cè)試的全部過(guò)程。

以上就是詳解golang項(xiàng)目開(kāi)發(fā)如何創(chuàng)建自己的Module的詳細(xì)內(nèi)容,更多關(guān)于golang創(chuàng)建Module的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一文讀懂go中semaphore(信號(hào)量)源碼

    一文讀懂go中semaphore(信號(hào)量)源碼

    這篇文章主要介紹了一文讀懂go中semaphore(信號(hào)量)源碼的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Go語(yǔ)言基礎(chǔ)go build命令用法及示例詳解

    Go語(yǔ)言基礎(chǔ)go build命令用法及示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)go build命令用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-11-11
  • Golang分布式鎖詳細(xì)介紹

    Golang分布式鎖詳細(xì)介紹

    分布式鎖是控制分布式系統(tǒng)之間同步訪問(wèn)共享資源的一種方式。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問(wèn)這些資源時(shí),需要通過(guò)一些互斥手段來(lái)防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了
    2022-10-10
  • go語(yǔ)言日志實(shí)現(xiàn)詳解(打印日志、日志寫(xiě)入文件和日志切割)

    go語(yǔ)言日志實(shí)現(xiàn)詳解(打印日志、日志寫(xiě)入文件和日志切割)

    golang內(nèi)置了log包,實(shí)現(xiàn)簡(jiǎn)單的日志服務(wù),下面這篇文章主要給大家介紹了關(guān)于go語(yǔ)言日志實(shí)現(xiàn)(打印日志、日志寫(xiě)入文件和日志切割)的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • Go 并發(fā)編程Goroutine的實(shí)現(xiàn)示例

    Go 并發(fā)編程Goroutine的實(shí)現(xiàn)示例

    Go語(yǔ)言中的并發(fā)編程主要通過(guò)Goroutine和Channel來(lái)實(shí)現(xiàn),本文就來(lái)介紹一下Go 并發(fā)編程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • Golang二維切片初始化的實(shí)現(xiàn)

    Golang二維切片初始化的實(shí)現(xiàn)

    這篇文章主要介紹了Golang二維切片初始化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • go語(yǔ)言的panic和recover函數(shù)用法實(shí)例

    go語(yǔ)言的panic和recover函數(shù)用法實(shí)例

    今天小編就為大家分享一篇關(guān)于go語(yǔ)言的panic和recover函數(shù)用法實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • 關(guān)于go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由的問(wèn)題

    關(guān)于go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由的問(wèn)題

    這篇文章主要介紹了go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由,涉及到Golang環(huán)境安裝及配置Go Module的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Golang Slice和map的坑

    Golang Slice和map的坑

    Golang中的Slice和Map在內(nèi)存空間上,有一些不同,本文主要介紹了Golang Slice和map的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換

    golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換

    這篇文章主要給大家介紹了關(guān)于golang基礎(chǔ)之字符串與int、int64類型互相轉(zhuǎn)換的相關(guān)資料,在Go語(yǔ)言中string轉(zhuǎn)int是一項(xiàng)常見(jiàn)的操作,需要的朋友可以參考下
    2023-07-07

最新評(píng)論