os
包以跨平台的方式,提供了一些与操作系统交互的函数和变量。程序的命令行参数可从os包的Args变量获取;os包外部使用os.Args访问该变量。s[i]
访问单个元素,用s[m:n]
获取子序列(译注:和python里的语法差不多)。序列的元素数目为len(s)。和大多数编程语言类似,区间索引时,Go言里也采用左闭右开形式, 即,区间包括第一个索引元素,不包括最后一个, 因为这样可以简化逻辑。(译注:比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3],不包含最后一个元素)。比如s[m:n]这个切片,0 ≤ m ≤ n ≤ len(s),包含n-m个元素。import
声明。两种形式都合法,列表形式习惯上用得多。包导入顺序并不重要;gofmt工具格式化时按照字母顺序对包名排序。(示例有多个版本时,我们会对示例编号, 这样可以明确当前正在讨论的是哪个。)//
开头。对于程序员来说,//之后到行末之间所有的内容都是注释,被编译器忽略。按照惯例,我们在每个包的包声明前添加注释;对于main package
,注释包含一句或几句话,从整体角度对程序做个描述。+
运算符连接字符串(译注:和C++或者js是一样的)。所以表达式:+=
是赋值运算符(assignment operator),每种数值运算符或逻辑运算符,如+
或*
,都有对应的赋值运算符。:=
是短变量声明(short variable declaration)的一部分, 这是定义一个或多个变量并根据它们的初始值为这些变量赋予适当类型的语句。下一章有这方面更多说明。i++
给i
加1;这和i += 1
以及i = i + 1
都是等价的。对应的还有i--
给i
减1。它们是语句,而不像C系的其它语言那样是表达式。所以j = i++
非法,而且++和--都只能放在变量名后面,因此--i
也非法。condition
是一个布尔表达式(boolean expression),其值在每次循环迭代开始时计算。如果为true
则执行循环体语句。post
语句在循环体执行结束后执行,之后再次对conditon
求值。condition
值为false
时,循环结束。initialization
和post
,分号也可以省略:condition
也省略了,像下面这样:break
或return
语句。for
循环的另一种形式, 在某种数据类型的区间(range)上遍历,如字符串或切片。echo
的第二版本展示了这种形式:range
产生一对值;索引以及在该索引处的元素值。这个例子不需要索引,但range
的语法要求, 要处理元素, 必须处理索引。一种思路是把索引赋值给一个临时变量, 如temp
, 然后忽略它的值,但Go语言不允许使用无用的局部变量(local variables),因为这会导致编译错误。空标识符
(blank identifier),即_
(也就是下划线)。空标识符可用于任何语法需要变量名但程序逻辑不需要的时候, 例如, 在循环里,丢弃不需要的循环索引, 保留元素值。大多数的Go程序员都会像上面这样使用range
和_
写echo
程序,因为隐式地而非显示地索引os.Args,容易写对。echo
的这个版本使用一条短变量声明来声明并初始化s
和seps
,也可以将这两个变量分开声明,声明一个变量有好几种方式,下面这些都等价:+=
连接原字符串、空格和下个参数,产生新字符串, 并把它赋值给s
。s
原来的内容已经不再使用,将在适当时机对它进行垃圾回收。strings
包的Join
函数:Println
为我们格式化输出。strings.Join
得到的结果很像,只是被放到了一对方括号里。切片都会被打印成这种格式。echo
程序,使其能够打印os.Args[0]
,即被执行命令本身的名字。echo
程序,使其打印每个参数的索引和值,每个一行。strings.Join
的版本的运行时间差异。(1.6节讲解了部分time
包,11.4节展示了如何写标准测试程序,以得到系统性的性能评测。)