2015-12-09 07:45:11 +00:00
## 1.1. Hello, World
2016-04-05 07:11:21 +00:00
我们以现已成为传统的“hello world”案例来开始吧, 这个例子首次出现于1978年出版的C语言圣经[《The C Programming Language》](http://s3-us-west-2.amazonaws.com/belllabs-microsite-dritchie/cbook/index.html)( 译注: 本书作者之一Brian W. Kernighan也是《The C Programming Language》一书的作者) 。C语言是直接影响Go语言设计的语言之一。这个例子体现了Go语言一些核心理念。
2015-12-09 07:45:11 +00:00
2016-01-20 13:08:13 +00:00
< u > < i > gopl.io/ch1/helloworld< / i > < / u >
2015-12-09 07:45:11 +00:00
```go
package main
import "fmt"
func main() {
2015-12-22 02:37:13 +00:00
fmt.Println("Hello, 世界")
2015-12-09 07:45:11 +00:00
}
```
2016-04-05 07:11:21 +00:00
Go是一门编译型语言, Go语言的工具链将源代码及其依赖转换成计算机的机器指令( 译注: 静态编译) 。Go语言提供的工具都通过一个单独的命令`go`调用,`go`命令有一系列子命令。最简单的一个子命令就是run。这个命令编译一个或多个以.go结尾的源文件, 链接库文件, 并运行最终生成的可执行文件。( 本书使用$表示命令行提示符。)
2015-12-09 07:45:11 +00:00
```
$ go run helloworld.go
```
2015-12-22 02:37:13 +00:00
2016-02-15 03:06:34 +00:00
毫无意外,这个命令会输出:
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
2015-12-22 02:37:13 +00:00
Hello, 世界
2015-12-09 07:45:11 +00:00
```
2016-02-15 03:06:34 +00:00
Go语言原生支持Unicode, 它可以处理全世界任何语言的文本。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
如果不只是一次性实验, 你肯定希望能够编译这个程序, 保存编译结果以备将来之用。可以用build子命令:
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
$ go build helloworld.go
```
2016-04-05 07:11:21 +00:00
这个命令生成一个名为helloworld的可执行的二进制文件( 译注: Windows系统下生成的可执行文件是helloworld.exe, 增加了.exe后缀名) , 之后你可以随时运行它( 译注: 在Windows系统下在命令行直接输入helloworld.exe命令运行) , 不需任何处理( 译注: 因为静态编译, 所以不用担心在系统库更新的时候冲突, 幸福感满满) 。
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
$ ./helloworld
2015-12-22 02:37:13 +00:00
Hello, 世界
2015-12-09 07:45:11 +00:00
```
2016-02-15 03:06:34 +00:00
本书中, 所有的示例代码上都有一行标记,利用这些标记, 可以从[gopl.io](http://gopl.io)网站上本书源码仓库里获取代码:
2015-12-09 07:45:11 +00:00
2015-12-22 02:37:13 +00:00
```
gopl.io/ch1/helloworld
```
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
执行 `go get gopl.io/ch1/helloworld` 命令, 就会从网上获取代码, 并放到对应目录中( 需要先安装Git或Hg之类的版本管理工具, 并将对应的命令添加到PATH环境变量中。序言已经提及, 需要先设置好GOPATH环境变量, 下载的代码会放在`$GOPATH/src/gopl.io/ch1/helloworld`目录) 。2.6和10.7节有这方面更详细的介绍。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
来讨论下程序本身。Go语言的代码通过**包**( package) 组织, 包类似于其它语言里的库( libraries) 或者模块( modules) 。一个包由位于单个目录下的一个或多个.go源代码文件组成, 目录定义包的作用。每个源文件都以一条`package`声明语句开始,这个例子里就是`package main`, 表示该文件属于哪个包, 紧跟着一系列导入( import) 的包, 之后是存储在这个文件里的程序语句。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
Go的标准库提供了100多个包, 以支持常见功能, 如输入、输出、排序以及文本处理。比如`fmt`包,就含有格式化输出、接收输入的函数。`Println`是其中一个基础函数,可以打印以空格间隔的一个或多个值,并在最后添加一个换行符,从而输出一整行。
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
`main` 包比较特殊。它定义了一个独立可执行的程序,而不是一个库。在`main`里的`main` *函数* 也很特殊, 它是整个程序执行时的入口( 译注: C系语言差不多都这样) 。`main`函数所做的事情就是程序做的。当然了,`main`函数一般调用其它包里的函数完成很多工作, 比如, `fmt.Println` 。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
必须告诉编译器源文件需要哪些包,这就是`import`声明以及随后的`package`声明扮演的角色。hello world例子只用到了一个包, 大多数程序需要导入多个包。
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
必须恰当导入需要的包, 缺少了必要的包或者导入了不需要的包, 程序都无法编译通过。这项严格要求避免了程序开发过程中引入未使用的包( 译注: Go语言编译过程没有警告信息, 争议特性之一) 。
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
`import` 声明必须跟在文件的`package`声明之后。随后,则是组成程序的函数、变量、常量、类型的声明语句(分别由关键字`func`, `var` , `const` , `type` 定义)。这些内容的声明顺序并不重要(译注:最好还是定一下规范)。这个例子的程序已经尽可能短了,只声明了一个函数, 其中只调用了一个其他函数。为了节省篇幅,有些时候, 示例程序会省略`package`和`import`声明,但是,这些声明在源代码里有,并且必须得有才能编译。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
一个函数的声明由`func`关键字、函数名、参数列表、返回值列表(这个例子里的`main`函数参数列表和返回值都是空的)以及包含在大括号里的函数体组成。第五章进一步考察函数。
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
Go语言不需要在语句或者声明的末尾添加分号, 除非一行上有多条语句。实际上, 编译器会主动把特定符号后的换行符转换为分号, 因此换行符添加的位置会影响Go代码的正确解析( 译注: 比如行末是标识符、整数、浮点数、虚数、字符或字符串文字、关键字`break`、`continue`、`fallthrough`或`return`中的一个、运算符和分隔符`++`、`--`、`)`、`]`或`}`中的一个)。举个例子, 函数的左括号`{`必须和`func`函数声明在同一行上, 且位于末尾,不能独占一行,而在表达式`x + y`中,可在`+`后换行,不能在`+`前换行(译注:以+结尾的话不会被插入分号分隔符, 但是以x结尾的话则会被分号分隔符, 从而导致编译错误) 。
2015-12-09 07:45:11 +00:00
2016-04-05 07:11:21 +00:00
Go语言在代码格式上采取了很强硬的态度。`gofmt`工具把代码格式化为标准格式( 译注: 这个格式化工具没有任何可以调整代码格式的参数, Go语言就是这么任性) , 并且`go`工具中的`fmt`子命令会对指定包, 否则默认为当前目录, 中所有.go源文件应用`gofmt`命令。本书中的所有代码都被gofmt过。你也应该养成格式化自己的代码的习惯。以法令方式规定标准的代码格式可以避免无尽的无意义的琐碎争执( 译注: 也导致了Go语言的TIOBE排名较低, 因为缺少撕逼的话题) 。更重要的是, 这样可以做多种自动源码转换, 如果放任Go语言代码格式, 这些转换就不大可能了。
2015-12-09 07:45:11 +00:00
2016-02-15 03:06:34 +00:00
很多文本编辑器都可以配置为保存文件时自动执行`gofmt`,这样你的源代码总会被恰当地格式化。还有个相关的工具,`goimports`,可以根据代码需要, 自动地添加或删除`import`声明。这个工具并没有包含在标准的分发包中,可以用下面的命令安装:
2015-12-09 07:45:11 +00:00
```
$ go get golang.org/x/tools/cmd/goimports
```
2016-02-15 03:06:34 +00:00
对于大多数用户来说, 下载、编译包、运行测试用例、察看Go语言的文档等等常用功能都可以用go的工具完成。10.7节详细介绍这些知识。