go接收输入
在 Go 语言中,接收控制台(标准输入)输入的方式有多种,常见的包括使用 fmt 包、bufio 包以及 os.Stdin 直接读取。它们各有特点和适用场景,以下是主要方式及其区别:
1. fmt.Scan / fmt.Scanf / fmt.Scanln
特点:
- 简单易用,适合快速读取少量数据。
- 自动跳过前导空白字符(如空格、换行等)。
Scan会一直读到非空白字符;Scanln要求输入以换行符结束;Scanf支持格式化输入。
示例:
go
var name string
fmt.Print("请输入名字: ")
fmt.Scan(&name)
注意事项:
- 遇到空格会停止读取(对字符串而言),因此不能读取包含空格的整行。
- 如果输入不符合预期格式,可能造成后续读取混乱。
2. bufio.Reader.ReadString('\n') 或 ReadLine()
特点:
- 可以完整读取一行(包括空格)。
- 更高效,适合大量或频繁输入。
- 需要手动处理换行符(
ReadString('\n')会保留\n)。
示例:
go
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入名字: ")
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(input) // 去除换行符和空格
注意事项:
- 返回值包含错误,建议处理错误。
- 比
fmt.Scan更灵活,推荐用于读取整行文本。
3. bufio.Scanner
特点:
- 高层封装,简洁安全。
- 默认按行读取(也可自定义分隔符)。
- 自动处理缓冲区和换行符,不会保留
\n。 - 适用于逐行读取大输入(如日志、多行输入)。
示例:
go
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("请输入名字: ")
if scanner.Scan() {
name := scanner.Text()
fmt.Println("你输入的是:", name)
}
注意事项:
- 单行最大长度默认为 64KB,超过会报错(可通过
Scanner.Buffer调整)。 - 不适合需要精细控制读取位置的场景。
4. 直接使用 os.Stdin.Read()
特点:
- 最底层方式,直接从标准输入读取字节。
- 需要自行管理缓冲区、换行、编码等。
- 一般不推荐用于常规输入读取。
示例:
go
buf := make([]byte, 1024)
n, _ := os.Stdin.Read(buf)
input := string(buf[:n])
对比总结
| 方法 | 是否保留换行 | 能否读空格 | 是否自动跳过空白 | 适合场景 |
|---|---|---|---|---|
fmt.Scan |
否 | 否 | 是 | 快速读取简单变量 |
fmt.Scanln |
否 | 否 | 是(但要求换行结束) | 读取单个字段 |
fmt.Scanf |
否 | 否(除非格式指定) | 是 | 格式化输入 |
bufio.ReadString('\n') |
是 | 是 | 否 | 读取完整一行(含空格) |
bufio.Scanner |
否 | 是 | 否 | 安全高效地逐行读取 |
os.Stdin.Read |
是 | 是 | 否 | 底层字节操作 |
推荐使用方式
- 读取单个单词/数字 :
fmt.Scan - 读取整行(含空格) :
bufio.Scanner(首选)或bufio.ReadString('\n') - 高性能/大量输入 :
bufio.Scanner - 格式化输入(如 C 风格) :
fmt.Scanf(谨慎使用)