Tony Bai · Go 语言第一课
Tony Bai
资深架构师,tonybai.com 博主
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 59 讲
开篇词 (1讲)
结束语 (1讲)
Tony Bai · Go 语言第一课
15
15
1.0x
00:00/00:00
登录|注册

04|初窥门径:一个Go程序的结构是怎样的?

探讨Go统一的代码风格的利弊
Go Module构建模式的应用
go.sum文件的作用
使用go mod tidy命令自动添加依赖信息
go.mod文件的生成和内容
Go Module的引入解决复杂依赖管理问题
使用go run命令直接运行源码文件
使用go build命令进行编译
Go是一种编译型语言
Go源码编译和运行
导入其他包
main包和main函数
Go源码文件命名规则
包是Go语言的基本组成单元
思考题
Go Module
Go程序的编译
Go程序结构
Go程序的结构和编译

该思维导图由 AI 生成,仅供参考

你好,我是 Tony Bai。
经过上一讲的学习,我想现在你已经成功安装好至少一个 Go 开发环境了,是时候撸起袖子开始写 Go 代码了!
程序员这个历史并不算悠久的行当,却有着一个历史悠久的传统,那就是每种编程语言都将一个名为“hello, world”的示例作为这门语言学习的第一个例子,这个传统始于 20 世纪 70 年代那本大名鼎鼎的由布莱恩·科尼根(Brian W. Kernighan)与 C 语言之父丹尼斯·里奇(Dennis M. Ritchie)合著的《C 程序设计语言》。
在这一讲中,我们也将遵从传统,从编写一个可以打印出“hello, world”的 Go 示例程序开始我们正式的 Go 编码之旅。我希望通过这个示例程序你能够对 Go 程序结构有一个直观且清晰的认识。
在正式开始之前,我要说明一下,我们这节课对你开发 Go 程序时所使用的编辑器工具没有任何具体的要求。
如果你喜欢使用某个集成开发环境(Integrated Development Environment,IDE),那么就用你喜欢的 IDE 好了。如果你希望我给你推荐一些好用的 IDE,我建议你试试 GoLandVisual Studio Code(简称 VS Code)。GoLand 是知名 IDE 出品公司 JetBrains 针对 Go 语言推出的 IDE 产品,也是目前市面上最好用的 Go IDE;VS Code 则是微软开源的跨语言源码编辑器,通过集成语言插件(Go 开发者可以使用 Go 官方维护的 vscode-go 插件),可以让它变成类 IDE 的工具。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
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-20
    17
    72
  • return
    老师讲的太好了, 重点细节 都很到位,赞啊。 请教老师: 如果 路径和包名不一样, path: apath, package: apack 那么使用的时候是这样吗? import "apath" apack.Print()

    作者回复: 你的理解非常正确,给你点个赞!

    2021-10-20
    3
    56
  • 多选参数
    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-14
    7
    48
  • Hans
    配置国内镜像代理(使用阿里云镜像) go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/ 验证 go env|grep GOPROXY

    作者回复: 嗯,国内的几大goproxy服务都是可以的。

    2021-10-21
    4
    25
  • 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-20
    4
    25
  • 自由
    关于思考题,我认为统一的代码风格是很有必要的。 在多人协作时,我们的代码存放在 git 仓库中,git 的代码提交记录,文件中的缩进和折行也会被视为改动。假如两位同学的格式化风格不同,提交代码时,一个文件中的实际改动与 git 记录的改动将会相差甚远!100 行代码就会多出 100 行改动,而实际上,有效改动可能仅仅是几行代码,在追溯问题时,带来很多不必要的麻烦。

    作者回复: 作为一个多年gopher的心底话,现在go开发已经完全离不开gofmt或类似工具了。并且这些标准风格格式化工具与各种编辑器或IDE结合后,是在“quiet模式”下帮助开发者,并不需要开发者付出额外的工作量。

    2021-10-20
    18
  • 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-20
    4
    15
  • 隰有荷
    老师,我有些不理解的地方在于: 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-05
    2
    13
  • Demon.Lee
    如果与面向对象语言进行类比,go 语言中的包,是否可以类比成Java中的类呢?

    作者回复: 如果从编译的角度来讲,go包是编译的基本单位,每个go包编译为一个.a文件,每个java public class编译为一个class文件。它们的确有些类似。但从内容结构上来说,go包是一个命名空间的概念,可以包含go所有语法元素。java class就是一个拥有多个属性+方法的抽象。

    2021-10-26
    2
    10
  • Aeins
    go.mod 文件中 module 指令设置模块的模块路径,可以是任意的,不需要和文件系统对应。建议和项目目录名相同 包的导入路径为模块路径和相对模块根目录(go.mod所在目录)的相对路径组成 包名由 package 语句指定,建议和包的目录名相同(也可以不同) 模块和包都对应了一个文件系统目录

    作者回复: 👍

    2022-05-24
    8
收起评论
显示
设置
留言
84
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部