go tools与包管理

本文记录下学习 golang官方文档 里 go tools 和包管理相关知识的笔记。
go tools有些设计很让人困惑,网上文章讲不明白,无奈只能看官方文档

0. 太长不看

尽量用高版本go,最好用1.18以后的版本,不行就1.16
低版本工具链一坨* ,而且你还得花精力专门学习、记忆低版本工具和高版本工具有啥区别,逻辑贼绕

1. 环境变量

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

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

用go env -w改配置的话,改的是每个用户自己的配置文件


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,全局公用一个GOPATH很容易导致不同版本的包冲突。
为避免此问题,可以用goland IDE,IDE支持每个project单独配一个自己的GOPATH。该设置会被保存在工作目录的 .idea 目录下,不会被设置到环境变量的 GOPATH 中,但会在编译时使用到这个目录。
http://c.biancheng.net/view/88.html

2. 常用命令

2.1. go build构建

https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies
构建生成可执行文件。

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编译运行

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

# 当前目录
go run .

或者

# 一个文件
go run hello.go

3. 包管理

3.1. 代码组织

3.1.1. 模型

https://go.dev/doc/code

  • import单元
    go代码是按package(目录)组织的,作为一个import单元;
  • 发布单元
    多个相关package组成一个module,作为一个发布单元;
    A repository contains one or more modules.

作为对比, nodejs是:

java是:

  • import单元
    每个源码文件对应一个class, import的时候import这个class。即使这个类里有内部类,也是import这个文件对应的类
    这么讲有点绕,简单理解成import单元是文件即可
  • 发布单元
    用maven的话,每个maven archifact打出来的jar是一个发布单元

python:

3.1.2. 包级别访问控制

首字母小写: 同package可见

Internal Directories

首字母小写的可见性比较低,不方便实现“一个模块内可见、但是对模块外不可见”的效果。
使用internal可以实现这种效果。
以前写java的时候就觉得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/
https://www.jianshu.com/p/760c97ff644c

3.2.1. 仓库模型

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

3.2.1.1. vendor 机制

每个module可以有个目录、放所有自己依赖的包

go mod vendor 可以用于创建vendor、更新vendor

image.png

3.2.1.2. module cache

本地有个类似于“本地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.

官方叫这个"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. 去中心化远程仓库

go咋知道每个仓库的代码路径

https调仓库、看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时,有时候1.17和1.16会有兼容问题导致报错:
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

想用本地的、还没发布过的模块?

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

image.png

想用某个module的fork版本?
image.png

3.2.3. 与module相关的命令

Module-aware mode vs GOPATH mode

https://go.dev/ref/mod#mod-commands
很多时候会困惑,为啥同一个命令在有go.mod的目录敲和没go.mod目录敲,效果不一样?
这是因为,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 , 给项目添加依赖
    另一种方法是:先在代码里写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啥区别?为什么职责这么不清楚?
    官方文档说了,建议go get -d ,让go get只负责改go.mod文件,构建安装的事情交给go install来做;以后版本会默认 -d,废弃掉2、3步骤
    丑陋的设计 :(
    image.png

3.4. 应用管理: go install

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

image.png

  • 定位
    1.16之后,可以当做一键下载、安装命令行工具的包管理器了。
    但是,和专业的包管理器 (app store) 不同的是,go install 不会下载别人已经编译好的程序,而是下载下来后自己编译,所以慢。

  • 做的事情

  1. (1.16及之后版本) 下载
  2. 构建编译成二进制
  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

非常糟糕的设计,让用户去记忆这if else逻辑

能否用 go install 安装同一个应用的多个版本,让他们共存?

golang 的多版本共存,可以通过项目编译时指定 GOPATH 解决。
包的多版本共存,可以通过不同 GOPATH,或者 go modules 机制解决。
二进制应用的多版本共存,是 OS 的使用问题,解决方案有:

那么,通过 go install 安装的应用能否方便的切换版本?
不能,没有现成的工具。顶多每次换版本时,重新 go install 下载、编译指定版本

参考资料 & 阅读进度

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容