处理输入的简单程序都有一个差不多的设计结构:一个处理输入的循环,在每个元素上执行计算处理,在处理的同时或最后产生输出。

stdin
// Dup prints the text of each line that appears more than
// once in the standard input, preceded by its count.
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	//分行读取标准输入s,将s放入map统计出现次数
	input := bufio.NewScanner(os.Stdin)
	statistic := make(map[string]int)
	for input.Scan() {
		line := input.Text()
		statistic[line]++
	}
	//打印出现重复的输入
	for line, num := range statistic {
		if num > 1 {
			fmt.Printf("%s\t%d\n", line, num)
		}
	}
}
复制代码
input := bufio.NewScanner(os.Stdin)os.StdinFILEbufioScannerinput.Scan()input.Text()
statistic := make(map[string]int)mapmapkey/value==makemapmake

示例代码(以文件作为输入):

// Dup2 prints the count and text of lines that appear more than once
// in the input.  It reads from stdin file
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	//读取文件名
	var file string
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Paramater number error!")
		return
	} else {
		file = os.Args[1]
	}
	//打开文件
	f, err := os.Open(file)
	if err != nil {
		fmt.Fprintf(os.Stderr, "open file error: %v\n", err)
		return
	}

	//分行读取文件,将内容放入map统计出现次数
	input := bufio.NewScanner(f)
	statistic := make(map[string]int)
	for input.Scan() {
		line := input.Text()
		statistic[line]++
	}
	f.Close()

	//打印出现重复的输入
	for line, num := range statistic {
		if num > 1 {
			fmt.Printf("%s\t%d\n", line, num)
		}
	}
}
复制代码
os.Open*os.FileScanner
os.OpenerrorerrnilCloseerrnilFprintf

Go中错误处理在所有的高级语言中简直是一股清流啊,这其实贴合Go的开发思想,简单、直观。事实上,我们在设计代码逻辑的时候,本来就是在考虑两种情况,成功了往下走,失败了怎么办?我们在开发产品的时候,本质上在不断取舍,在可能出现错误的地方用分支语句处理就可以了,既符合逻辑又直白简单。

以上两种读取输入的方式都是使用的“流”模式,并根据需要拆分成多个行。理论上,这些程序可以处理任意数量的输入数据。还有另一个方法,就是一口气把全部输入数据读到内存中,一次分割为多行,然后处理它们。

示例代码(以文件作为输入):

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	//读取文件名
	var file string
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Paramater number error!")
		return
	} else {
		file = os.Args[1]
	}

	//读取文件所有内容
	data, err := ioutil.ReadFile(file)
	if err != nil {
		fmt.Fprintf(os.Stderr, "open file error: %v\n", err)
		return
	}

	//分行统计数据
	content := string(data)
	statistic := make(map[string]int)
	for _, line := range strings.Split(content, "\r\n") {
		statistic[line]++
	}

	//打印出现重复的输入
	for line, num := range statistic {
		if num > 1 {
			fmt.Printf("%s\t%d\n", line, num)
		}
	}
}
复制代码
ReadFilebyte slicestringstrings.Splitbufio.Scannerioutil.ReadFile ioutil.WriteFIle*os.FileReadWritebufioio/ioutil