1.2 一个简单的Go程序
在完成了Go语言开发环境的搭建后,我们正式开始Go语言的开发之旅。本节以打印一个简单的字符串“hello Golang”为例,讲述最简单的Go程序的执行,并解析其中每行代码的意义。
1.2.1 编写第一个Go程序
我们在任意文件夹下新建并编辑一个文件——first.go,其文件内容如下:
打开命令行终端(macOS/Linux的Terminal,Windows中的命令行),运行go run命令,执行结果如下:
$ go run first.go hello Golang
下面我们对上述简单Go程序进行解析。
1.声明包名
package main用于声明包名。包是函数的父级结构,用于管理函数。我们知道,所有应用程序都有一个执行入口,也是程序执行的起点。Go语言要求程序的入口必须是main包下的main方法。因为first.go是目前唯一的程序文件,所以该文件的包名必须声明为“main”,否则程序将无法正常运行。
2.导入其他包
import "fmt"用于导入其他包。需要注意的是“fmt”并不是包名,而是一个相对路径。import "fmt"实际是扫描该路径下的所有代码,以获得其中的函数、自定义类型等。相对路径的起点是Go语言的安装目录(GOROOT)下的src文件夹。在笔者的计算机上,该目录为/usr/local/go/src。我们可以在命令行中查看该目录,结果如下所示。
通过命令行的输出可以看到,fmt目录下有多个.go文件。利用import "fmt"可以导入fmt目录下的.go文件中定义的函数。例如,打开print.go文件,可以看到包名为fmt;同时,该文件中还有一个名为Println的函数。导入该函数后,便可以利用fmt.Println的形式(包名+函数名)进行调用。
需要注意的是,虽然print.go中的包名与该文件所在的目录名相同(均为“fmt”),但是包名和目录名是两个概念,二者也可以不同,我们将在6.3节进行详细讲述。
3.main()函数
func main()用于声明一个名为main的函数,该函数将作为程序的入口。
4.打印字符串
fmt.Println("hello Golang")作为函数main()的函数体。该语句调用了fmt包中的Println()函数,用于打印一个固定字符串“hello Golang”。
5.Go程序的基本结构
通过以上分析我们可以看到,一个简单的Go程序的基本结构可以概括为如图1-3所示的样子。
图1-3 first.go代码结构及函数调用示意图
1.2.2 运行第一个Go程序
go run命令是运行.go文件最直接的命令。在first.go所在的目录下,可以利用go run命令直接运行first.go文件,代码如下:
$ go run first.go hello Golang
go run命令封装了编译和执行的过程,我们也可以将该命令拆解为两个步骤:
利用go build命令进行编译:
通过输出结果可知,在当前目录下生成了名为first的文件。从文件属性(-rwxr-xr-x)也可以看出,所有用户都拥有可执行权限(即权限中的x标识位)。同时,也代表该文件是一个可执行文件。
直接运行first文件(在Windows环境中,双击即可执行文件),其输出如下所示。
$ ./first hello Golang
当然,go build的过程也是一个比较复杂的过程。我们将在“1.6 探寻Go语言程序的编译执行过程”中详细说明。
注意 可执行文件first的大小为1.8MB,而源码文件first.go仅仅只有75B。我们可以猜想,go build实际是将所有关联到的源码文件都包含进来,这导致Go语言编译出的可执行文件往往比较大。Go语言的编译不同于C++或者Java编译后的结果。C++可以引用动态链接库,而Java往往依赖外部JAR包。