1.3 第一个Go程序
自Kernighan和Ritchie合著的《C程序设计语言》(The C Programming Language)出版以来,几乎所有的编程书都以一个Hello world小例子作为开始。我们也不免俗(或者说尊重传统),下面我们从一个简单Go语言版本的Hello world来初窥Go这门新语言的模样,如代码清单1-4所示。
代码清单1-4 hello.go
package main import "fmt"// 我们需要使用fmt包中的Println()函数 func main() { fmt.Println("Hello, world. 你好,世界!") }
1.3.1 代码解读
每个Go源代码文件的开头都是一个package声明,表示该Go代码所属的包。包是Go语言里最基本的分发单位,也是工程管理中依赖关系的体现。要生成Go可执行程序,必须建立一个名字为main的包,并且在该包中包含一个叫main()的函数(该函数是Go可执行程序的执行起点)。
Go语言的main()函数不能带参数,也不能定义返回值。命令行传入的参数在os.Args变量中保存。如果需要支持命令行开关,可使用flag包。在本书后面我们将解释如何使用flag包来做命令行参数规范的定义,以及获取和解析命令行参数。
在包声明之后,是一系列的import语句,用于导入该程序所依赖的包。由于本示例程序用到了Println()函数,所以需要导入该函数所属的fmt包。
有一点需要注意,不得包含在源代码文件中没有用到的包,否则Go编译器会报编译错误。这与下面提到的强制左花括号{的放置位置以及之后会提到的函数名的大小写规则,均体现了Go语言在语言层面解决软件工程问题的设计哲学。
所有Go函数(包括在对象编程中会提到的类型成员函数)以关键字func开头。一个常规的函数定义包含以下部分:
func 函数名(参数列表)(返回值列表) {
// 函数体
}
对应的一个实例如下:
func Compute(value1 int, value2 float64)(result float64, err error) { // 函数体 }
Go支持多个返回值。以上的示例函数Compute()返回了两个值,一个叫result,另一个是err。并不是所有返回值都必须赋值。在函数返回时没有被明确赋值的返回值都会被设置为默认值,比如result会被设为0.0, err会被设为nil。
Go程序的代码注释与C++保持一致,即同时支持以下两种用法:
/* 块注释 */ // 行注释
相信熟悉C和C++的读者也发现了另外一点,即在这段Go示例代码里没有出现分号。Go程序并不要求开发者在每个语句后面加上分号表示语句结束,这是与C和C++的一个明显不同之处。
有些读者可能会自然地把左花括号{另起一行放置,这样做的结果是Go编译器报告编译错误,这点需要特别注意:
syntax error: unexpected semicolon or newline before {
1.3.2 编译环境准备
前面我们给大家大概介绍了第一个Go程序的基本结构,接下来我们来准备编译这段小程序的环境。
在Go 1发布之前,开发者要想使用Go,只能自行下载代码并进行编译,而现在可以直接下载对应的安装包进行安装,安装包的下载地址为http://code.google.com/p/go/downloads/list。
在*nix环境中,Go默认会被安装到/usr/local/go目录中。安装包在安装完成后会自动添加执行文件目录到系统路径中。
安装完成后,请重新启动命令行程序,然后运行以下命令以验证Go是否已经正确安装:
$ go version go version go1
如果该命令能够正常运行并输出相应的信息,说明Go编译环境已经正确安装完毕。如果提示找不到go命令,可以通过手动添加/usr/local/go/bin到PATH环境变量来解决。
1.3.3 编译程序
假设之前介绍的Hello, world代码被保存为了hello.go,并位于~/goyard目录下,那么可以用以下命令行编译并直接运行该程序:
$ cd ~/goyard $ go run hello.go # 直接运行 Hello, world. 你好,世界!
使用这个命令,会将编译、链接和运行3个步骤合并为一步,运行完后在当前目录下也看不到任何中间文件和最终的可执行文件。如果要只生成编译结果而不自动运行,我们也可以使用Go命令行工具的build命令:
$ cd ~/goyard $ go build hello.go $ ./hello Hello, world. 你好,世界!
可以看出,Go命令行工具是一个非常强大的源代码管理工具。我们将在第4章中详细讲解Go命令行工具所包含的更多更强大的功能。
从根本上说,Go命令行工具只是一个源代码管理工具,或者说是一个前端。真正的Go编译器和链接器被Go命令行工具隐藏在后面,我们可以直接使用它们:
$ 6g helloworld.go $ 6l helloworld.6 $ ./6.out Hello, world. 你好,世界!
6g和6l是64位版本的Go编译器和链接器,对应的32位版本工具为8g和8l。Go还有另外一个GCC版本的编译器,名为gccgo,但不在本书的讨论范围内。