程序使用短变量声明创建bufio.Scanner
类型的变量input
。
input := bufio.NewScanner(os.Stdin)
该变量从程序的标准输入中读取内容。每次调用input.Scan()
,即读入下一行,并移除行末的换行符;读取的内容可以调用input.Text()
得到。Scan
函数在读到一行时返回true
,不再有输入时返回false
。
类似于C或其它语言里的printf
函数,fmt.Printf
函数对一些表达式产生格式化输出。该函数的首个参数是个格式字符串,指定后续参数被如何格式化。各个参数的格式取决于“转换字符”(conversion character),形式为百分号后跟一个字母。举个例子,%d
表示以十进制形式打印一个整型操作数,而%s
则表示把字符串型操作数的值展开。
Printf
有一大堆这种转换,Go程序员称之为动词(verb)。下面的表格虽然远不是完整的规范,但展示了可用的很多特性:
%d 十进制整数
%x, %o, %b 十六进制,八进制,二进制整数。
%f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00
%t 布尔:true或false
%c 字符(rune) (Unicode码点)
%s 字符串
%q 带双引号的字符串"abc"或带单引号的字符'c'
%v 变量的自然形式(natural format)
%T 变量的类型
%% 字面上的百分号标志(无操作数)
dup1
的格式字符串中还含有制表符
和换行符
。字符串字面上可能含有这些代表不可见字符的转义字符(escape sequences)。默认情况下,Printf
不会换行。按照惯例,以字母f
结尾的格式化函数,如log.Printf
和fmt.Errorf
,都采用fmt.Printf
的格式化准则。而以ln
结尾的格式化函数,则遵循Println
的方式,以跟%v
差不多的方式格式化参数,并在最后添加一个换行符。(译注:后缀f
指format
,ln
指line
。)
很多程序要么从标准输入中读取数据,如上面的例子所示,要么从一系列具名文件中读取数据。dup
程序的下个版本读取标准输入或是使用os.Open
打开各个具名文件,并操作它们。
OS
os
包以跨平台的方式,提供了一些与操作系统交互的函数和变量。程序的命令行参数可从os包的Args变量获取;os包外部使用os.Args访问该变量。
os.Args变量是一个字符串(string)的切片(slice)(译注:slice和Python语言中的切片类似,是一个简版的动态数组),切片是Go语言的基础概念,稍后详细介绍。现在先把切片s当作数组元素序列, 序列的长度动态变化, 用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个元素。
os.Args的第一个元素,os.Args[0], 是命令本身的名字;其它的元素则是程序启动时传给它的参数。s[m:n]形式的切片表达式,产生从第m个元素到第n-1个元素的切片,下个例子用到的元素包含在os.Args[1:len(os.Args)]切片中。如果省略切片表达式的m或n,会默认传入0或len(s),因此前面的切片可以简写成os.Args[1:]。