go get 和 go install 對比介紹
一、問題背景
安裝Go庫db2struct時,使用go get命令執(zhí)行
go get ``github.com/Shelnutt2/db2struct/cmd/db2struct,
執(zhí)行db2struct -h報錯:
zsh: command not found: db2struct
改為go install命令執(zhí)行
go install ``github.com/Shelnutt2/db2struct/cmd/db2struct
后成功執(zhí)行db2struct -h,同時ls $GOPATH/bin也看到了可執(zhí)行文件db2struct。
二、原因探究
(一)命令定義和區(qū)別
go install 和 go get 都是 Go 語言的工具命令,但它們之間有一些區(qū)別。
go get:用于從遠(yuǎn)程代碼存儲庫(如 GitHub)中下載或更新 Go 代碼包。它會下載代碼包并將其存儲在$GOPATH/src目錄下對應(yīng)的位置,并編譯代碼包中的程序和庫。如果目標(biāo)包之前已經(jīng)被下載過了,那么go get會嘗試更新到最新版本,并重新編譯程序和庫文件。在更新完代碼包后,go get還會自動把下載的代碼包的可執(zhí)行文件復(fù)制到$GOPATH/bin目錄下,以方便直接使用該可執(zhí)行文件。go install:用于編譯并安裝 Go 代碼包,并將其生成的可執(zhí)行程序或庫文件存儲到$GOPATH/bin或者$GOPATH/pkg目錄下。如果你在項目目錄下執(zhí)行go install,它將會編譯并安裝當(dāng)前項目的代碼,生成可執(zhí)行文件并將其保存到$GOPATH/bin目錄下(如果項目是一個庫,則生成的是.a文件,并將其存儲到$GOPATH/pkg目錄下)。
因此,go get 用于下載和更新代碼包,并產(chǎn)生對應(yīng)的可執(zhí)行程序,而 go install 用于將一個 Go 代碼包轉(zhuǎn)化為可執(zhí)行程序或庫文件,并安裝到系統(tǒng)路徑以供直接使用。
使用表格形式對 go get 和 go install 進(jìn)行比較:
| 命令 | 功能 | 下載位置 | 生成文件位置 |
|---|---|---|---|
| go get | 從遠(yuǎn)程代碼庫中下載或更新 Go 代碼包 | $GOPATH/src | $GOPATH/bin |
| go install | 編譯并安裝 Go 代碼包 | 無需下載自身代碼,$GOPATH/src 用于依賴包的查找 | GOPATH/bin或GOPATH/bin 或 GOPATH/bin或GOPATH/pkg |
(二)go get 是否包含了 go install
可以認(rèn)為 go get 命令包含了 go install 命令的功能,但它們之間還是存在一些細(xì)微差別。
go get 命令用于從遠(yuǎn)程代碼庫中下載或更新 Go 代碼包,并自動編譯生成相應(yīng)的可執(zhí)行程序,同時還將其安裝到 $GOPATH/bin 目錄下,以便簡化程序的運行。go get 命令不需要指定包的路徑,它會使用 Go 語言規(guī)范中約定的包導(dǎo)入路徑來獲取包信息,并自動處理包的依賴關(guān)系以方便編譯。
相比之下,go install 命令則更為靈活,它可以編譯并安裝當(dāng)前項目的代碼,生成可執(zhí)行文件或庫,并將其保存在 $GOPATH/bin 或 $GOPATH/pkg 目錄下。同時,go install 命令還可以通過指定 -ldflags 參數(shù)來修改二進(jìn)制文件的鏈接標(biāo)志,從而將一些自定義的元信息加入到二進(jìn)制文件中,使得可以在運行時通過代碼讀取這些信息。
在 Go 1.16 版本之后,go get 命令已經(jīng)默認(rèn)使用了 Go 模塊管理工具。而 go install 命令則始終需要先進(jìn)入到處于 Go 模塊管理的路徑下,然后才能使用該命令編譯并安裝相關(guān)代碼包。
綜上所述,可以認(rèn)為 go get 命令包含了 go install 命令的部分功能,但是在一些特殊情況下,還是需要使用 go install 命令來進(jìn)行更靈活的編譯和安裝操作。
(三)為什么要用 go install
在使用 go get 命令下載并安裝代碼包時,有些情況下生成的可執(zhí)行文件可能無法生效,這通常是因為 Go 語言版本不兼容或編譯環(huán)境不同導(dǎo)致的。而使用 go install 命令則可以避免這些問題,下面列舉了幾種常見情況:
- 版本不兼容:如果
go get命令下載的代碼包和當(dāng)前使用的 Go 語言版本不兼容,那么go get命令可能會產(chǎn)生編譯錯誤或生成無法運行的可執(zhí)行文件。對于這種情況,使用go install命令可以保證使用的是當(dāng)前系統(tǒng)上與 Go 語言版本兼容的編譯器。 - 編譯環(huán)境不同:在使用
go get命令下載代碼包時,有時它們的編譯環(huán)境與當(dāng)前環(huán)境不同,可能會導(dǎo)致可執(zhí)行文件無法正常工作。而在使用go install命令時,該命令會在當(dāng)前環(huán)境下重新編譯源代碼并生成可執(zhí)行文件,從而能夠更加穩(wěn)定地運行代碼。 - 依賴關(guān)系復(fù)雜:在使用
go get命令下載大型的代碼包時,它可能會自動下載和安裝大量依賴項。這樣可能會導(dǎo)致依賴關(guān)系變得復(fù)雜而難以管理,有時可能會在下載或編譯依賴項時產(chǎn)生錯誤或警告。而go install命令會直接從當(dāng)前路徑下對應(yīng)依賴項中尋找依賴項,因此可以避免這種情況下帶來的復(fù)雜性和錯誤。
綜上所述,盡管 go get 命令十分方便快捷,但在遇到一些特殊情況時,仍然需要使用 go install 命令以獲得更加穩(wěn)定的編譯和安裝效果。
可以使用如下表格來對比 go get 和 go install 的編譯區(qū)別:
| 命令 | 功能 | 編譯效果 | 應(yīng)用場景 |
|---|---|---|---|
| go get | 下載或更新 Go 代碼包并生成可執(zhí)行文件 | 可能由于版本或編譯環(huán)境的不同,生成的可執(zhí)行文件無法運行或出現(xiàn)其他問題 | 需要快速下載和安裝指定版本的 Go 代碼包,如果生成的可執(zhí)行文件無法運行,則需要使用 go install 命令重新編譯 |
| go install | 編譯并安裝 Go 代碼并生成可執(zhí)行文件或庫 | 在當(dāng)前環(huán)境下重新編譯源代碼并生成可執(zhí)行文件或庫,能夠更加穩(wěn)定地運行代碼包 | 需要在當(dāng)前環(huán)境下重新編譯 Go 代碼并生成二進(jìn)制文件,需要避免由于版本不兼容、編譯環(huán)境不同或依賴關(guān)系復(fù)雜性導(dǎo)致的編譯錯誤和生成的可執(zhí)行文件無法運行的問題。 |
到此這篇關(guān)于go get 和 go install 對比介紹的文章就介紹到這了,更多相關(guān)go get和go install對比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang1.23版本之前 Timer Reset方法無法正確使用
在Go 1.23之前,使用`time.Reset`函數(shù)時需要先調(diào)用`Stop`并明確從timer的channel中抽取出東西,以避免潛在的問題,然而,這在實際代碼中難以實現(xiàn),因為設(shè)置定時器狀態(tài)和發(fā)送channel的操作并不是原子的,在某些情況下,這會導(dǎo)致timer在不應(yīng)該觸發(fā)時提前觸發(fā)2025-01-01
Go1.20最新資訊go?arena手動管理內(nèi)存鴿了
由于過于繁雜,Go?核心團隊成員@Ian?Lance?Taylor,也表態(tài):目前尚未做出任何決定,也不可能在短期內(nèi)做出任何決定,可以認(rèn)為這個提案基本鴿了,今天這篇文章就是給大家同步目前的情況2023-11-11
解決golang 反射interface{}做零值判斷的一個重大坑
這篇文章主要介紹了解決golang 反射interface{}做零值判斷的一個重大坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
深入了解Golang?interface{}的底層原理實現(xiàn)
在?Go?語言沒有泛型之前,接口可以作為一種替代實現(xiàn),也就是萬物皆為的?interface。那到底?interface?是怎么設(shè)計的底層結(jié)構(gòu)呢?下面咱們透過底層分別看一下這兩種類型的接口原理。感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助2022-10-10

