Go中的模块
有时,我们会遇到需要阅读自己不熟悉语言的情况,比如:Go。
对于一个常规项目而言,模块是必然会涉及到的概念。如果要分析Go写的项目,就必须要掌握Go的模块和它的基本语法。掌握基本语法相对比较容易,因为Go借鉴了C语言的一些语法,如果熟悉类C语言,那么,阅读Go的代码也会有一定的熟悉感。
但是,Go的模块(包,导入等语法)却是由Oberon-2启发而来,所以,Go的模块和当下流行语言的设计(Java,Python,JavaScript等)有很大不同。
总的来说,一个Go项目就是一个模块,一个模块会包含很多包(package),一个包中会包含多个go文件,每个go文件中可以定义多个函数。
它们之间的关系链为:模块 > 包 > 文件 > 函数。
模块
为了初始化一个项目(模块),我们可以使用命令来完成:
cd some_dir
go mod init demo首先,使用cd命令进入到项目根目录下。然后,使用 go mod init 来初始化模块。其中,demo是模块名称。当执行完成后,会在根目录下出现两个文件: go.mod 和 go.sum。这两个文件记录了该项目的基本信息,比如:项目名称、Go的版本、依赖的第三方库等信息,作用和前端项目的 package.json 和 package-lock.json(或 Python 中的 requirements.txt)类似。
模块初始化完成后,就可以在这个模块下面组织业务逻辑了。
包
包是 Go 程序中的最小复用单位。同一个文件夹下的所有 .go 文件必须属于同一个包(通常包名就是文件夹名)。
以一个小型Web项目为例,通常用 MVC 来区分不同的包,比如:model包、router包、view包等。
以Go自带的fmt 包为例,它下面有 print.go、format.go等文件。
另外,package main很特殊。它告诉 Go 编译器,这个包应该被编译成一个可执行程序,该包必须包含一个 func main() 函数作为程序的入口点。
最后,除 mian 包外,其他的包,建议名称和文件夹名字一样(强烈推荐)
go文件
在一个go文件中,我们可以编写多个函数。
以 fmt 包中的 print.go 为例,它定义了多个函数,比如:Printf、Sprintf、Fprintf和Println等。
函数
函数是最小功能单元。这意味着所有的业务逻辑,最终都会落地到函数身上。
第一次接触Go的人会很疑惑,为什么函数名首字母是大写的?
这是一个奇怪的设定(个人认为优雅):首字母大写表示它是公开的,可以被其他包(Package)访问。例如:fmt.Println() 中的 Println 是大写的,所以你能在自己的包里用它。首字母小写表示它是私有的,只能在当前包的内部使用,外部包无法看到它。我觉得这个设定简单明了,不用像Java那样写Public和Private关键字来区分可见性。它符合Go的设计哲学:简单。