go tools與包管理

本文記錄下學(xué)習(xí) golang官方文檔 里 go tools 和包管理相關(guān)知識的筆記。
go tools有些設(shè)計(jì)很讓人困惑,網(wǎng)上文章講不明白,無奈只能看官方文檔

0. 太長不看

盡量用高版本go,最好用1.18以后的版本,不行就1.16
低版本工具鏈一坨* ,而且你還得花精力專門學(xué)習(xí)、記憶低版本工具和高版本工具有啥區(qū)別,邏輯賊繞

1. 環(huán)境變量

https://pkg.go.dev/cmd/go#hdr-Environment_variables

go env 查看生效的配置、修改配置

用go env -w改配置的話,改的是每個(gè)用戶自己的配置文件


image.png

下載不到包? 掛代理!

export GOPROXY=https://goproxy.cn

http://c.biancheng.net/view/5712.html

GOROOT 和 GOPATH

https://stackoverflow.com/questions/7970390/what-should-be-the-values-of-gopath-and-goroot
https://go.dev/doc/code
https://blog.csdn.net/huyoo/article/details/22715307
https://my.oschina.net/achun/blog/134002

在低版本golang中,沒有modules或者沒開啟modules,全局公用一個(gè)GOPATH很容易導(dǎo)致不同版本的包沖突。
為避免此問題,可以用goland IDE,IDE支持每個(gè)project單獨(dú)配一個(gè)自己的GOPATH。該設(shè)置會被保存在工作目錄的 .idea 目錄下,不會被設(shè)置到環(huán)境變量的 GOPATH 中,但會在編譯時(shí)使用到這個(gè)目錄。
http://c.biancheng.net/view/88.html

2. 常用命令

2.1. go build構(gòu)建

https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies
構(gòu)建生成可執(zhí)行文件。

When compiling multiple packages or a single non-main package, build compiles the packages but discards the resulting object, serving only as a check that the packages can be built.

2.2. go run編譯運(yùn)行

https://pkg.go.dev/cmd/go#hdr-Compile_and_run_Go_program
例如

# 當(dāng)前目錄
go run .

或者

# 一個(gè)文件
go run hello.go

3. 包管理

3.1. 代碼組織

3.1.1. 模型

https://go.dev/doc/code

  • import單元
    go代碼是按package(目錄)組織的,作為一個(gè)import單元;
  • 發(fā)布單元
    多個(gè)相關(guān)package組成一個(gè)module,作為一個(gè)發(fā)布單元;
    A repository contains one or more modules.

作為對比, nodejs是:

java是:

  • import單元
    每個(gè)源碼文件對應(yīng)一個(gè)class, import的時(shí)候import這個(gè)class。即使這個(gè)類里有內(nèi)部類,也是import這個(gè)文件對應(yīng)的類
    這么講有點(diǎn)繞,簡單理解成import單元是文件即可
  • 發(fā)布單元
    用maven的話,每個(gè)maven archifact打出來的jar是一個(gè)發(fā)布單元

python:

3.1.2. 包級別訪問控制

首字母小寫: 同package可見

Internal Directories

首字母小寫的可見性比較低,不方便實(shí)現(xiàn)“一個(gè)模塊內(nèi)可見、但是對模塊外不可見”的效果。
使用internal可以實(shí)現(xiàn)這種效果。
以前寫java的時(shí)候就覺得java需要這種功能。

go help gopath
image.png

https://golang.org/s/go14internal

3.2. modules

https://go.dev/doc/code
https://www.cnblogs.com/rickiyang/p/13874139.html
https://zhuanlan.zhihu.com/p/92992277
https://zhuanlan.zhihu.com/p/60703832
https://tonybai.com/2019/09/21/brief-history-of-go-package-management/
http://www.itdecent.cn/p/760c97ff644c

3.2.1. 倉庫模型

模型是:
vendor --- local module cache --- decentralized remote repo

3.2.1.1. vendor 機(jī)制

每個(gè)module可以有個(gè)目錄、放所有自己依賴的包

go mod vendor 可以用于創(chuàng)建vendor、更新vendor

image.png

3.2.1.2. module cache

本地有個(gè)類似于“本地maven倉庫”的“本地中央倉庫”,支持多版本
Module dependencies are automatically downloaded to the pkg/mod subdirectory of the directory indicated by the GOPATH environment variable. The downloaded contents for a given version of a module are shared among all other modules that require that version, so the go command marks those files and directories as read-only.

官方叫這個(gè)"module cache"

  • 刪掉所有module
    To remove all downloaded modules, you can pass the -modcache flag to go clean:

go clean -modcache

  • GOPATH and Modules
go help gopath

GOPATH and Modules

When using modules, GOPATH is no longer used for resolving imports.
However, it is still used to store downloaded source code (in GOPATH/pkg/mod)
and compiled commands (in GOPATH/bin).

3.2.1.3. 去中心化遠(yuǎn)程倉庫

go咋知道每個(gè)倉庫的代碼路徑

https調(diào)倉庫、看meta
https://ehang-io.github.io/blog.ehang.io/2020/01/22/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1golang%E5%8C%85%E4%B8%8Egithub%E4%BB%93%E5%BA%93%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D%E9%85%8D%E7%BD%AE/
https://golang.org/cmd/go/#hdr-Remote_import_paths

3.2.2. go.mod

  • go mod tidy
    The go mod tidy command adds missing module requirements for imported packages and removes requirements on modules that aren't used anymore.

敲go mod tidy時(shí),有時(shí)候1.17和1.16會有兼容問題導(dǎo)致報(bào)錯(cuò):
https://www.cnblogs.com/zjhgx/p/15336147.html

image.png

不知道啥意思,我按建議敲命令 go mod tidy -go=1.16 && go mod tidy -go=1.17解決

replace

go.mod里可以用replace替換指定包的版本,比如替換成本地版本
https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/

但是replace只在主模塊生效:

image.png

https://golang.org/ref/mod#go-mod-file-replace

想用本地的、還沒發(fā)布過的模塊?

https://go.dev/doc/modules/managing-dependencies

image.png

想用某個(gè)module的fork版本?
image.png

3.2.3. 與module相關(guān)的命令

Module-aware mode vs GOPATH mode

https://go.dev/ref/mod#mod-commands
很多時(shí)候會困惑,為啥同一個(gè)命令在有g(shù)o.mod的目錄敲和沒go.mod目錄敲,效果不一樣?
這是因?yàn)?,go命令有兩種模式,Most go commands may run in Module-aware mode or GOPATH mode

image.png

3.3. go get

https://go.dev/doc/modules/managing-dependencies

image.png

https://go.dev/ref/mod#go-get

  • 做的事情
  1. 改go.mod , 給項(xiàng)目添加依賴
    另一種方法是:先在代碼里寫import ,然后go mod tidy
  2. builds the packages named on the command line
  3. Executables will be installed in the directory named by the GOBIN environment variable
  • 對比 go install
    你看了2、3肯定想噴:這和go install啥區(qū)別?為什么職責(zé)這么不清楚?
    官方文檔說了,建議go get -d ,讓go get只負(fù)責(zé)改go.mod文件,構(gòu)建安裝的事情交給go install來做;以后版本會默認(rèn) -d,廢棄掉2、3步驟
    丑陋的設(shè)計(jì) :(
    image.png

3.4. 應(yīng)用管理: go install

https://go.dev/ref/mod#go-install
https://go.dev/doc/modules/managing-dependencies

image.png

  • 定位
    1.16之后,可以當(dāng)做一鍵下載、安裝命令行工具的包管理器了。
    但是,和專業(yè)的包管理器 (app store) 不同的是,go install 不會下載別人已經(jīng)編譯好的程序,而是下載下來后自己編譯,所以慢。

  • 做的事情

  1. (1.16及之后版本) 下載
  2. 構(gòu)建編譯成二進(jìn)制
  3. 安裝成本地命令
    Non-executable packages are built and cached but not installed.
  • 兩種模式: module-aware mode or GOPATH mode


    image.png

    1.16以前go install不能指定版本,不會自動去下載包,需要你自己用go get下載好;


    image.png

1.16以后可以指定版本,可以幫你下載
https://play-with-go.dev/installing-go-programs-directly_go116_en/

image.png

非常糟糕的設(shè)計(jì),讓用戶去記憶這if else邏輯

能否用 go install 安裝同一個(gè)應(yīng)用的多個(gè)版本,讓他們共存?

golang 的多版本共存,可以通過項(xiàng)目編譯時(shí)指定 GOPATH 解決。
包的多版本共存,可以通過不同 GOPATH,或者 go modules 機(jī)制解決。
二進(jìn)制應(yīng)用的多版本共存,是 OS 的使用問題,解決方案有:

那么,通過 go install 安裝的應(yīng)用能否方便的切換版本?
不能,沒有現(xiàn)成的工具。頂多每次換版本時(shí),重新 go install 下載、編譯指定版本

參考資料 & 閱讀進(jìn)度

https://www.zhihu.com/question/23486344

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容