最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go 語言中程序編譯過程詳解

 更新時間:2024年05月31日 16:54:17   作者:栗箏i  
本文旨在深入探討Go語言的編譯機制和最新的模塊管理系統(tǒng)——Go Modules,通過詳細的示例和步驟,我們將演示從簡單的 “Hello World” 程序到使用第三方庫的更復雜項目的開發(fā)過程,感興趣的朋友跟隨小編一起看看吧

在當今快速發(fā)展的軟件開發(fā)領(lǐng)域,Go 語言(又稱 Golang)已經(jīng)成為了開發(fā)高性能應(yīng)用程序的熱門選擇。由 Google 開發(fā)并在 2009 年公開發(fā)布,Go 語言因其簡潔的語法、出色的并發(fā)支持以及優(yōu)秀的性能而受到廣泛歡迎。盡管 Go 的語法相對簡單,但它的編譯過程和模塊管理系統(tǒng)可能會讓初學者感到有些困惑,特別是那些從動態(tài)語言背景轉(zhuǎn)來的開發(fā)者。

本文旨在深入探討 Go 語言的編譯機制和最新的模塊管理系統(tǒng)——Go Modules。通過詳細的示例和步驟,我們將演示從簡單的 “Hello World” 程序到使用第三方庫的更復雜項目的開發(fā)過程。我們將開始于基本的編譯命令,探索如何手動處理依賴,然后過渡到使用 Go Modules 管理依賴,這在現(xiàn)代 Go 項目開發(fā)中已成為標準實踐。

1、編譯和運行 Go 程序的基礎(chǔ)

在上一篇我們實現(xiàn) HelloWorld 程序的過程中,我們在運行 “helloworld” 程序之前,是輸入了一個 go build 命令的:

$go build main.go

對此,如果有使用 C/C++ 和 gcc 或 clang 的開發(fā)經(jīng)驗的同學家就會發(fā)現(xiàn) Go 的編譯步驟與它們非常類似。都是在編譯成功后,生成一個二進制可執(zhí)行文件。

在 Linux 系統(tǒng)、macOS 系統(tǒng)或 Windows 系統(tǒng)的 PowerShell 中,可以通過執(zhí)行以下 ls 命令來查看這個新生成的可執(zhí)行文件:

$ls
main*    main.go

可以看到,在上面顯示的文件里面有我們剛剛創(chuàng)建的、以 .go 為后綴的源代碼文件,還有剛生成的可執(zhí)行文件(Windows 系統(tǒng)下為 main.exe,其余系統(tǒng)下為 main)。

如果你主要使用的是像 Ruby、Python 或 JavaScript 這樣的動態(tài)語言,那么你可能不太習慣需要在運行程序之前先進行編譯的步驟。

Go 是編譯型語言,這意味著我們必須先編譯 Go 程序,才能將生成的可執(zhí)行文件交給其他人,在沒有安裝 Go 的環(huán)境中也能運行這些程序。相對地,如果你提供給別人的是 .rb、.py.js 文件,他們就需要在自己的環(huán)境中安裝相應(yīng)的 Ruby、Python 或 JavaScript 解釋器來執(zhí)行這些動態(tài)語言的源代碼。

當然,Go 也借鑒了動態(tài)語言的一些對開發(fā)者體驗較好的特性,比如基于源碼文件的直接執(zhí)行,Go 提供了 run 命令可以直接運行 Go 源碼文件,比如我們也可以使用下面命令直接基于 main.go 運行:

$go run main.go
hello, world

不過像 go run 這類命令更多用于開發(fā)調(diào)試階段,真正的交付成果還是需要使用 go build 命令構(gòu)建的。

然而,在我們的生產(chǎn)環(huán)境中,編譯 Go 程序通常不像之前提到的基于單個 Go 源文件構(gòu)建像"hello, world"這樣的簡單示例那么直接。隨著項目接近真實的生產(chǎn)條件,它的規(guī)模會增大、涉及的協(xié)作人員會增多,同時項目的依賴及其版本也會變得更為復雜。

2、Go Modules 機制

2.1、復雜項目下 Go 程序的編譯

現(xiàn)在,我們將啟動一個名為"hellomod"的新項目,在這個項目中,我們會使用兩個第三方庫:zapfasthttp。這將使 go build 的構(gòu)建過程更具挑戰(zhàn)性。

如同我們之前的"helloworld"示例一樣,我們可以通過以下命令來創(chuàng)建“hellomod”項目:

$mkdir hellomod
$cd hellomod

接著,我們在"hellomod"下創(chuàng)建并編輯我們的示例源碼 main.go 文件:

package main
import (
  "github.com/valyala/fasthttp"
  "go.uber.org/zap"
)
var logger *zap.Logger
func init() {
  logger, _ = zap.NewProduction()
}
func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
  logger.Info("hello, go module", zap.ByteString("uri", ctx.RequestURI()))
}
func main() {
  fasthttp.ListenAndServe(":8081", fastHTTPHandler)
}

這個示例中,我們創(chuàng)建了一個在 8081 端口上監(jiān)聽的 HTTP 服務(wù)。當向該服務(wù)發(fā)起請求時,它會在終端的標準輸出上打印一段訪問日志???/p>

以看出,相比于“hello, world”示例,這個項目明顯更加復雜。但目前,我們不需要深入了解每行代碼的具體作用。只要應(yīng)該我們在這個稍微復雜的示例中使用了兩個第三方依賴庫:zapfasthttp。

接下來,讓我們嘗試使用編譯"hello, world"時的方法來編譯“hellomod”項目中的 main.go 源文件,看看 Go 編譯器會給出什么樣的輸出結(jié)果:

$go build main.go
main.go:4:3: no required module provides package github.com/valyala/fasthttp: go.mod file not found in current directory or any parent directory; see 'go help modules'
main.go:5:3: no required module provides package go.uber.org/zap: go.mod file not found in current directory or any parent directory; see 'go help modules'

從編譯器的輸出來看,go build 似乎在找一個名為 go.mod 的文件,來解決程序?qū)Φ谌桨囊蕾嚊Q策問題。

2.2、go mod

Go 1.11 版本推出 modules 機制,簡稱 mod,更加易于管理項目中所需要的模塊。模塊是存儲在文件樹中的 Go 包的集合,其根目錄中包含 go.mod 文件。 go.mod 文件定義了模塊的模塊路徑,它也是用于根目錄的導入路徑,以及它的依賴性要求。每個依賴性要求都被寫為模塊路徑和特定語義版本。

Go 1.11 開始,Go 允許在 $GOPATH/src 外的任何目錄下使用 go.mod 創(chuàng)建項目。在 $GOPATH/src 中,為了兼容性,Go 命令仍然在舊的 GOPATH 模式下運行。從 Go 1.13 開始,go.mod模式將成為默認模式。

2.3、go mod 示例

現(xiàn)在,我們將通過以下命令為“hellomod”示例程序創(chuàng)建一個 go.mod 文件:

go mod init github.com/lizhengi/hellomod
go: creating new go.mod: module github.com/lizhengi/hellomod
go: to add module requirements and sums:
	go mod tidy

Ps:注意模塊命名方式,如果你的項目要發(fā)布到 github,則命名為:github.com/<USERNAME>/<MODULE_NAME>

此時可以看到,go mod init 命令的執(zhí)行結(jié)果是在當前目錄下生成了一個 go.mod 文件:

$cat go.mod
module github.com/lizhengi/hellomod
go 1.17

實際上,一個 module 是多個包的集合,這些包與 module 一起進行版本控制、發(fā)布和分發(fā)。go.mod 文件所在的目錄被視為聲明的 module 的根目錄。此時的 go.mod 文件內(nèi)容相對簡單,首行是用來聲明 module 路徑(module path)的。Module 本質(zhì)上引入了命名空間的概念,這意味著 module 下每個包的導入路徑都由 module path 和包所在的子目錄名共同構(gòu)成。

例如,在 hellomod 下有一個子目錄 pkg/pkg1,那么 pkg1 中的包的導入路徑將是 github.com/lizhengi/hellomod/pkg/pkg1。此外,go.mod 文件的最后一行是 Go 版本指示符,表示該 module 是基于特定 Go 版版本的 module 語義編寫的。

此時,我們執(zhí)行一下構(gòu)建,Go 編譯器輸出結(jié)果是這樣的

$go build main.go
main.go:4:2: no required module provides package github.com/valyala/fasthttp; to add it:
  go get github.com/valyala/fasthttp
main.go:5:2: no required module provides package go.uber.org/zap; to add it:
  go get go.uber.org/zap

你會看到,Go 編譯器提示源碼依賴 fasthttp 和 zap 兩個第三方包,但是 go.mod 中沒有這兩個包的版本信息,我們需要按提示手工添加信息到 go.mod 中。

這個時候,除了按提示手動添加外,我們也可以使用 go mod tidy 命令,讓 Go 工具自動添加:

$go mod tidy                       
go: finding module for package go.uber.org/zap
go: finding module for package github.com/valyala/fasthttp
go: downloading github.com/valyala/fasthttp v1.54.0
go: downloading go.uber.org/zap v1.27.0
go: found github.com/valyala/fasthttp in github.com/valyala/fasthttp v1.54.0
go: found go.uber.org/zap in go.uber.org/zap v1.27.0
go: downloading go.uber.org/multierr v1.10.0
go: downloading github.com/stretchr/testify v1.8.1
go: downloading go.uber.org/goleak v1.3.0
go: downloading github.com/andybalholm/brotli v1.1.0
go: downloading github.com/klauspost/compress v1.17.7
go: downloading github.com/valyala/bytebufferpool v1.0.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading github.com/pmezard/go-difflib v1.0.0

Ps:超時的話換個代理即可

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

Go 工具不僅下載并添加了 hellomod 直接依賴的 zap 和 fasthttp 包的信息,還下載了這兩個包的相關(guān)依賴包。go mod tidy 執(zhí)行后,我們 go.mod 的最新內(nèi)容變成了這個樣子:

module github.com/bigwhite/hellomod
go 1.16
require (
  github.com/valyala/fasthttp v1.28.0
  go.uber.org/zap v1.18.1
)

此時,go.mod 文件已經(jīng)包含了 hellomod 直接依賴的包的信息。此外,在 hellomod 目錄下還出現(xiàn)了一個名為 go.sum 的文件,這個文件記錄了 hellomod 的直接依賴和間接依賴包的版本 hash 值,這用于校驗本地包的真實性。在構(gòu)建過程中,如果本地依賴包的 hash 值與 go.sum 文件中的記錄不匹配,構(gòu)建會被拒絕。

有了 go.mod 以及 hellomod 依賴的包版本信息后,我們再來執(zhí)行構(gòu)建:

$go build main.go
go: downloading go.uber.org/zap v1.27.0
go: downloading github.com/valyala/fasthttp v1.54.0
go: downloading go.uber.org/multierr v1.10.0
go: downloading github.com/andybalholm/brotli v1.1.0
go: downloading github.com/klauspost/compress v1.17.7
go: downloading github.com/valyala/bytebufferpool v1.0.0
$ls
go.mod    go.sum    main*    main.go

這次我們成功構(gòu)建出了可執(zhí)行文件 main,運行這個文件,新開一個終端窗口,在新窗口中使用 curl 命令訪問該 http 服務(wù):curl localhost:8081/foo/bar,我們就會看到服務(wù)端輸出如下日志:

$./main
{"level":"info","ts":1716950836.531074,"caller":"hellomod/main.go:15","msg":"hello, go module","uri":"/foo/bar"}

到此這篇關(guān)于Go 語言中程序是怎么編譯的?的文章就介紹到這了,更多相關(guān)Go程序編譯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言學習之指針的用法詳解

    Go語言學習之指針的用法詳解

    這篇文章主要為大家詳細介紹了Go語言中指針的用法,文中的示例代碼講解詳細,對我們學習Go語言有一定的幫助,需要的可以參考一下
    2022-04-04
  • 關(guān)于golang中平行賦值淺析

    關(guān)于golang中平行賦值淺析

    這篇文章主要給大家介紹了關(guān)于golang中平行賦值的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用golang具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • Golang測試func?TestXX(t?*testing.T)的使用詳解

    Golang測試func?TestXX(t?*testing.T)的使用詳解

    一般Golang中的測試代碼都以xxx_test.go的樣式,在命名測試函數(shù)的時候以Testxx開頭,下面給大家介紹Golang測試func?TestXX(t?*testing.T)的使用,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • GoLang橋接模式的實現(xiàn)示例

    GoLang橋接模式的實現(xiàn)示例

    橋接模式是一種結(jié)構(gòu)型設(shè)計模式,通過橋接模式可以將抽象部分和它的實現(xiàn)部分分離,本文主要介紹了GoLang橋接模式,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 基于Go語言實現(xiàn)簡單網(wǎng)絡(luò)聊天室(命令行模式)

    基于Go語言實現(xiàn)簡單網(wǎng)絡(luò)聊天室(命令行模式)

    這篇文章主要為大家詳細介紹了如何基于Go語言實現(xiàn)簡單網(wǎng)絡(luò)聊天室,文中的示例代碼簡潔易懂,有需要的小伙伴可以跟隨小編一起學習一下
    2025-02-02
  • 使用Go語言生成Excel任務(wù)表依賴圖的代碼實現(xiàn)

    使用Go語言生成Excel任務(wù)表依賴圖的代碼實現(xiàn)

    在游戲中,任務(wù)是非常常見的玩法,可能會有主線任務(wù),支線任務(wù)以及其它一些類型的任務(wù),當任務(wù)比較多的時候,它們的依賴關(guān)系將變得不直觀,很容易出錯,所以本文介紹了使用Go語言生成Excel任務(wù)表依賴圖的代碼實現(xiàn),需要的朋友可以參考下
    2025-09-09
  • etcd通信接口之客戶端API核心方法實戰(zhàn)

    etcd通信接口之客戶端API核心方法實戰(zhàn)

    這篇文章主要為大家介紹了etcd通信接口之客戶端API核心方法實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Golang中零切片、空切片、nil切片

    Golang中零切片、空切片、nil切片

    切片是最常用的數(shù)據(jù)結(jié)構(gòu)之一,但許多開發(fā)者對零切片、空切片和nil切片的概念模糊不清,本文主要介紹了這三種的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2025-06-06
  • Golang易錯知識點匯總

    Golang易錯知識點匯總

    這篇文章匯總了在開發(fā)和刷面試題過程中遇到的Golang容易搞錯的知識點,關(guān)鍵部分也都為大家寫了代碼示例,感興趣的小伙伴可以了解一下
    2022-09-09
  • Go語言切片??嫉拿嬖囌骖}解析

    Go語言切片常考的面試真題解析

    了解最新的Go語言面試題型,讓面試不再是難事,下面這篇文章主要給大家介紹了關(guān)于Go語言切片面試??嫉囊恍﹩栴},文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02

最新評論

秀山| 宜春市| 崇州市| 闽清县| 根河市| 常山县| 江山市| 蒙阴县| 仙桃市| 宿松县| 长兴县| 庆安县| 靖江市| 仙游县| 乡宁县| 福贡县| 个旧市| 华宁县| 平江县| 珲春市| 嘉荫县| 呼和浩特市| 喀喇沁旗| 尖扎县| 普定县| 安义县| 荆门市| 松原市| 南郑县| 嘉祥县| 连云港市| 措美县| 长顺县| 丰顺县| 清原| 理塘县| 怀柔区| 双桥区| 塔河县| 永顺县| 永昌县|