How can I store/copy a single user input in multiple variables in Golang?

huangapple go评论83阅读模式
英文:

How can I store/copy a single user input in multiple variables in Golang?

问题

package main

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

var counter int = 0

func main() {

	var (
		read1 *bufio.Scanner
	)

	read1 = bufio.NewScanner(os.Stdin)
	read2 := read1
	count_lines(read1)
	read2.Scan()
	fmt.Println("read2: ", read2.Text())
	os.Exit(0)
}

func count_lines(read *bufio.Scanner){
   read.Scan()
   fmt.Println("read1: ", read.Text())
   if read.Text() == ""{
     return
   }
   counter++
   count_lines(read)
}

所以,我正在尝试使用递归来计算用户输入的行数。我还想在不同的函数中处理相同的输入。但是当我使用Scan()时,它会逐行解析输入一次。read2变量为空。有没有办法正确地复制用户输入?
如果我没有解释清楚,我很抱歉。我是Go的新手,我一点也不懂。我附上了一张参考图片。
参考图片
谢谢。


<details>
<summary>英文:</summary>

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
	&quot;bufio&quot;
  )

var counter int = 0
func main() {

	var (
		read1 *bufio.Scanner;
	)

	read1 = bufio.NewScanner(os.Stdin);
	read2 := read1
	count_lines(read1)
	read2.Scan()
	fmt.Println(&quot;read2: &quot;, read2.Text())
	os.Exit(0);
}

func count_lines(read *bufio.Scanner){
   read.Scan();
   fmt.Println(&quot;read1: &quot;, read.Text())
   if read.Text() == &quot;&quot;{
     return;
   }
   counter++;
   count_lines(read);
}

So, I&#39;m trying to count lines of my user input using recursion. And I also want to work on the same input in a different function. But when I use Scan(), it parses through the input line by line once. The read2 variable is empty. Is there a way to properly copy the user input?
I&#39;m sorry if I couldn&#39;t explain properly. I&#39;m new to Go and I don&#39;t understand any of it. I&#39;ve attached an image for reference.
[reference][1]
Thank You.


  [1]: https://i.stack.imgur.com/wAIuu.jpg

</details>


# 答案1
**得分**: 1

欢迎来到StackOverflow和Go!

我将尝试以一种易于理解但不一定准确的方式解释情况。所以,为了从键盘读取输入,你正在使用一个名为`read1`的“扫描器”:

```go
read1 = bufio.NewScanner(os.Stdin)

然后,你“复制”了那个“扫描器”,并将其命名为read2

read2 := read1

所以现在当你使用read1扫描器调用count_lines函数时,你会计算输入的行数,直到输入一个空行为止。
然后,你假设当你完成行数统计后,read2将能够再次读取相同的行。但实际情况并非如此。

实际发生的情况可以用以下方式更好地说明。想象一下,read1read2是两把镐⛏️,你可以用它们来挖掘地面中的某些东西。
所以你拿起一把你亲切地称之为read1的镐,然后敲击地面(相当于read.Scan())。然后你拿起你挖到的那块东西,检查里面有什么(read.Text())。然后,你重复这个过程,直到你完成挖掘或者直到read.Text() == ""

当你完成时,你拿起名为read2的⛏️...你不能再次挖掘同样的东西,对吧?这基本上就是扫描器的工作原理。

所以为了解决这个问题,你可以对自己说,我不需要两把镐,一把就足够了,但是我想要保留并首先分析从地面挖出的东西(count_lines),然后在第二次挖掘中寻找黄金(或其他你喜欢的东西)。

所以你的代码可能如下所示:

package main

import (
  "fmt"
  "os"
  "bufio"
)
var counter int = 0
var myLines = ""
func main() {

  var (
    read1 *bufio.Scanner;
  )

  read1 = bufio.NewScanner(os.Stdin);
  count_lines(read1)
  fmt.Println("read2: ");
  fmt.Println(myLines)
  os.Exit(0);
}

func count_lines(read *bufio.Scanner) {
  read.Scan();
  line := read.Text();
  myLines += line + "\n";
  fmt.Println("read1: ", line)
  if read.Text() == ""{
    return;
  }
  counter++;
  count_lines(read);
}

注意:这不是惯用的(推荐的)做法。我尽量改动原始代码的部分最少。

英文:

Welcome to StackOverflow, and Go!

I'll try to explain the situation in a hopefully understandable and not necessarily technically accurate way.
So, in order to read input from the keyboard you're using a 'scanner' that you 'named' read1:

read1 = bufio.NewScanner(os.Stdin)

Then you 'copied' that 'scanner' and named it read2

read2 := read1

So now when you call count_lines with the read1 scanner you count the lines until an empty line is entered.
And, then, you assumed that when you're done with the line counting, read2 will be able to read the same lines again. But this isn't how it works.

What actually happens is better illustrated with the following. Imagine read1 and read2 are two pickaxes ⛏️ that you can use to dig something out of the ground.
So you take a pickaxe you kindly named read1 and hit a ground (this is equal to read.Scan()). Then you pick up the piece you got and check what is inside (read.Text()). You, then, repeat the process until you're done pickaxing or until - read.Text() == &quot;&quot;.

When you're done, you take the ⛏️ named read2 and... You cannot pickaxe the same thing again, right? And that is basically how the scanner works.

So to deal with it you can say to yourself, I don't need two pickaxes, one is enough but whatever I excavated from the ground I want to keep and analyze it first for diamonds (count_lines) and then in the second pass for gold (or whatever you like).

So your code might look like:

package main

import (
  &quot;fmt&quot;
  &quot;os&quot;
  &quot;bufio&quot;
)
var counter int = 0
var myLines = &quot;&quot;
func main() {

  var (
    read1 *bufio.Scanner;
  )

  read1 = bufio.NewScanner(os.Stdin);
  count_lines(read1)
  fmt.Println(&quot;read2: &quot;);
  fmt.Println(myLines)
  os.Exit(0);
}

func count_lines(read *bufio.Scanner) {
  read.Scan();
  line := read.Text();
  myLines += line + &quot;\n&quot;;
  fmt.Println(&quot;read1: &quot;, line)
  if read.Text() == &quot;&quot;{
    return;
  }
  counter++;
  count_lines(read);
}

Note: This is not the idiomatic (recommended) way of doing things. I aimed at changing as little of the original code as possible.

huangapple
  • 本文由 发表于 2021年11月16日 08:15:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/69982414.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定