04|初窥门径:一个Go程序的结构是怎样的?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Go语言是一门流行的编程语言,本文以“hello, world”示例程序为例,介绍了Go程序的结构和编写过程。文章首先讲解了“hello, world”示例程序的结构,包括包的定义、main函数的特殊性以及代码风格规范。接着详细介绍了Go语言的编译过程,强调了Go是一种编译型语言,需要先编译成可执行文件才能运行。此外,还介绍了在生产环境中使用go build命令进行编译的复杂性。文章还通过一个复杂项目的示例展示了Go程序的编译过程,包括依赖管理和使用Go Module构建模式。通过这些内容,读者可以快速了解Go程序的特点和基本操作,以及Go语言的包管理和构建模式。文章内容详实,适合对Go语言感兴趣的读者阅读。
《Tony Bai · Go 语言第一课》,新⼈⾸单¥59
全部留言(84)
- 最新
- 精选
- swordholder如何import自己在本地创建的module,在这个module还没有发布到GitHub的情况下?
作者回复: 非常好的问题。go module机制在您提到的工作场景下目前的体验做的还不够好。在Go 1.17版本及之前版本的解决方法是使用go mod的replace指示符(directive)。假如你的module a要import的module b将发布到github.com/user/repo中,那么你可以手动在module的go.mod中的require块中手工加上一条: require github.com/user/repo v1.0.0 注意v1.0.0这个版本号是一个临时的版本号。 然后在module a的go.mod中使用replace将上面对module b的require替换为本地的module b: replace github.com/user/repo v1.0.0 => module b本地路径 这样go命令就会使用你本地正在开发、尚未提交github的module b了。 你可以试试。
2021-10-201772 - return老师讲的太好了, 重点细节 都很到位,赞啊。 请教老师: 如果 路径和包名不一样, path: apath, package: apack 那么使用的时候是这样吗? import "apath" apack.Print()
作者回复: 你的理解非常正确,给你点个赞!
2021-10-20356 - 多选参数go 引用了其他包的话,是将引用的包都编译进去。我用 ldd 才看几个 go 编译出来的二进制程序都是没有动态链接库的使用。但是,在看其他几个 go 编译出来的二进制程序时(比如 containerd、ctr,它们都是用 go 编写的),又有引用动态链接库,这个是为什么?
作者回复: go默认是开启CGO_ENABLED的,即CGO_ENABLED=1。但编译出来的二进制程序究竟有无动态链接,取决于你的程序使用了什么包。如果就是一个hello,world,那么你编译出来的将是一个纯静态程序。 如果你依赖了网络包或一些系统包,比如用http包编写了一个web server(见第9讲示例),那么你编译出来的二进制程序又会是一个包含动态链接的程序。 原因就在于目前的go标准库中,某些功能具有两份实现,一份是c语言实现的,一份是go语言实现的。在cgo_enable开启的情况下,go链接器会链接c语言的版本,于是就有了依赖动态链接库的情况。如果你将cgo_enabled置为0,你再重新编译链接,那么go链接器会使用go版本的实现,这样你将得到一个没有动态链接的纯静态二进制程序。
2021-11-14748 - Hans配置国内镜像代理(使用阿里云镜像) go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/ 验证 go env|grep GOPROXY
作者回复: 嗯,国内的几大goproxy服务都是可以的。
2021-10-21425 - william前面能看懂,后面就开始迷了。。。 Go Module 的概念我还是不怎么理解, 很多教程都用github.com... 做例子, 你说的是”路径“,路径不应该是 (win10)"D:\goprojects\hellomodule" 吗?我自己自定义一个任意的名字也可以正常运行?我感觉很奇怪,为什么很多人用github.com/...做module呢? 还有go mod tidy 命令后,下载的包在哪?在Go语言安装路径的src文件夹中?还是在哪?
作者回复: 1. 使用github.com/...作为module path是因为多数实用级module多是上传到github上的。用这种示例便于后续与真实生产接驳。但对于本地开发使用的简单示例程序而言,你说的没错。module path可以任意起,比如: module demo1 也是ok的。 第二个问题,go mod tidy下载的第三方包一般在$GOPATH/pkg/mod下面。如果没有设置GOPATH环境变量,其默认值为你的home路径下的go文件夹。这样第三方包就在go文件夹的pkg/mod下面。
2021-10-20425 - 自由关于思考题,我认为统一的代码风格是很有必要的。 在多人协作时,我们的代码存放在 git 仓库中,git 的代码提交记录,文件中的缩进和折行也会被视为改动。假如两位同学的格式化风格不同,提交代码时,一个文件中的实际改动与 git 记录的改动将会相差甚远!100 行代码就会多出 100 行改动,而实际上,有效改动可能仅仅是几行代码,在追溯问题时,带来很多不必要的麻烦。
作者回复: 作为一个多年gopher的心底话,现在go开发已经完全离不开gofmt或类似工具了。并且这些标准风格格式化工具与各种编辑器或IDE结合后,是在“quiet模式”下帮助开发者,并不需要开发者付出额外的工作量。
2021-10-2018 - lesserror感谢Tony Bai老师这么细致的讲解。能够基于最新的Go Module来讲解,正好是我想要的。 之前看了太多基于go path的教程。感觉Go Module比之前的go path清晰多了。 有几个问题想要了解下: 1. 老师这节课的源码目录为什么不是类似:src/github.com/xxx 这样的方式在本地构建呢? 我看很多地方,建议以这种方式来创建项目。 2. go mod tidy 这个命令中的 tidy 该如何翻译比较准确呢? 这个命令平时还挺常用的,希望结合中文翻译去加深记忆。 ps: 希望后面老师能够,结合Go项目的代码访问路径,来系统讲解一下,代码的访问流程。
作者回复: 问题1:go module与gopath的一个重要区别就是可以将项目放在任意路径下,而无需局限在$GOPATH/src下面。我之所以将一个module放在一个任意路径下,就是故意要与GOPATH模式区分开的。 问题2:有些时候,无论怎么翻译都不能很理想的呈现英文作者的原意,因此向go mod tidy我倾向于直接使用原文,而不要翻译为中文。 关于你的建议,我后续会重点考虑的,感谢。
2021-10-20415 - 隰有荷老师,我有些不理解的地方在于: 1、 1-1、go mod init 后面跟的路径规则是什么样的? 1-2、这个命令本身是什么含义? 1-3、文中所说的module,到底哪个是module,是go.mod文件是module,还是hellomodule这个文件夹是module?因为我看文章中说当前文件夹是module的根目录,所以这里不太理解。 2、我在执行go mod tidy 之后出现报错:go: warning: "all" matched no packages。但是我每一步都和文章中的步骤一样,请问是哪里出现了问题?
作者回复: 1-1. go mod init后面的路径就是go.mod中module后面的路径,代表的是module path。 1-2. go mod init命令的实际行为就是在当前目录下创建一个go.mod,而这个go.mod将当前目录转换为一个go module。 1-3. go module是一个逻辑概念。文中也说了,它更像一个命名空间的概念。它与文件夹名称无关。有了go.mod后,这个文件夹下的各个包就算是这个go module下面的包了。包的导入路径也是以module path为前缀的。 2. 确认一下你本地的go编译器版本?确认go module构建模式已开启。确认一下是否在go.mod所在目录执行的go mod tidy?
2021-11-05213 - Demon.Lee如果与面向对象语言进行类比,go 语言中的包,是否可以类比成Java中的类呢?
作者回复: 如果从编译的角度来讲,go包是编译的基本单位,每个go包编译为一个.a文件,每个java public class编译为一个class文件。它们的确有些类似。但从内容结构上来说,go包是一个命名空间的概念,可以包含go所有语法元素。java class就是一个拥有多个属性+方法的抽象。
2021-10-26210 - Aeinsgo.mod 文件中 module 指令设置模块的模块路径,可以是任意的,不需要和文件系统对应。建议和项目目录名相同 包的导入路径为模块路径和相对模块根目录(go.mod所在目录)的相对路径组成 包名由 package 语句指定,建议和包的目录名相同(也可以不同) 模块和包都对应了一个文件系统目录
作者回复: 👍
2022-05-248