Go语言中如何将一份用户输入存储/拷贝到多个变量中使用?
问题根因
你直接赋值read2 := read1属于指针拷贝,两个变量指向同一个bufio.Scanner实例。bufio.Scanner对os.Stdin的读取是流式消费,一旦通过Scan()读完所有输入,不管用哪个指针操作都无法重复读取内容,且标准输入默认不支持回卷重读。
解决方案
方案1:全量缓存输入(推荐,适合大多数常规场景)
如果输入量级不大,最简单的方式是先把所有输入行读取到内存切片中,后续统计行数、其他逻辑都直接复用这个切片即可:
package main import ( "bufio" "fmt" "os" ) func main() { var lines []string scanner := bufio.NewScanner(os.Stdin) // 先把所有输入读到切片里 for scanner.Scan() { line := scanner.Text() if line == "" { // 遇到空行停止读取,和原递归逻辑一致 break } lines = append(lines, line) } // 统计行数直接取切片长度,无需递归 counter := len(lines) fmt.Println("总行数:", counter) // 其他处理逻辑直接遍历lines即可实现原read2需求 for _, line := range lines { fmt.Println("read2: ", line) } }
方案2:流式分流(适合输入量极大、不想全占内存的场景)
如果输入太大全量缓存会占用过多内存,可以用io.TeeReader把标准输入的内容分流,读取的时候同步写入缓存,统计完行数后再从缓存读取内容做其他处理:
package main import ( "bufio" "bytes" "fmt" "io" "os" ) func main() { var buf bytes.Buffer // 把stdin的读取内容同步写到buf缓存里 tee := io.TeeReader(os.Stdin, &buf) // 第一个Scanner用来统计行数 scanner1 := bufio.NewScanner(tee) counter := 0 for scanner1.Scan() { line := scanner1.Text() if line == "" { break } fmt.Println("read1:", line) counter++ } fmt.Println("总行数:", counter) // 第二个Scanner从缓存里读之前的输入内容 scanner2 := bufio.NewScanner(&buf) for scanner2.Scan() { fmt.Println("read2:", scanner2.Text()) } }
内容的提问来源于stack exchange,提问作者Abdullah Zaman Babar
相关产品推荐
相关产品推荐

