Why is there an err argument required for Scanln, and when i assign a variable to it, I cannot transfer it to byte data in the function WriteFile>?

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

Why is there an err argument required for Scanln, and when i assign a variable to it, I cannot transfer it to byte data in the function WriteFile>?

问题

为什么在fmt.Scanln函数中需要一个必需的错误err变量?
我还需要帮助理解fmt.Writeln参数的目的。

这个程序的目的是通过命令行从用户获取输入数据,并将其输出到一个名为go-log.go的文件中。

package main

import (
    "fmt"
    "os"
)

func main() {

    YNQ := "yes"

    for YNQ == "yes" {

        fmt.Println("What do you want to add to the log?")

        openfile, err := os.Open("go-log.txt")

        addedText, err := fmt.Scanln()

        os.WriteFile("go-log.txt", []byte(addedText), 0666)

        // 在这里添加日期和时间

        fmt.Println("Would you like to add anything else?")

        fmt.Scanln(&YNQ)
    }
    openfile.Close()
}
  • 收到的错误:

    • 无法将addedText(类型为int)转换为[byte]类型
    • 未定义:openfile
英文:

Why is there is a required error err variable for the fmt.Scanln function?
I also need help understanding the purpose of the fmt.Writeln parameters.

The purpose of this program is to get input data from the user by the command line and output it to a file go-log.go

package main

import ("fmt"
        "os")

func main() {

  YNQ := "yes"

  for YNQ == "yes" {

    fmt.Println("What do you want to add to the log?")

    openfile, err := os.Open("go-log.txt")

    addedText, err := fmt.Scanln()

    os.WriteFile("go-log.txt", []byte(addedText), 0666)

    //add date and time here

    fmt.Println("Would you like to add anything else?")

    fmt.Scanln(&YNQ)
  }
  openfile.Close()
}
  
 - errors recieved:
   
       -cannot convert addedText (type int) to type [byte]
       -undefined: openfile

</details>


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

首先让我们使用`go fmt`命令使你的代码可读性更好

```Go
package main

import (
	"fmt"
	"os"
)

func main() {
	YNQ := "yes"
	for YNQ == "yes" {
		fmt.Println("What do you want to add to the log?")
		openfile, err := os.Open("go-log.txt")
		addedText, err := fmt.Scanln()
		os.WriteFile("go-log.txt", []byte(addedText), 0666)
		//在这里添加日期和时间
		fmt.Println("Would you like to add anything else?")
		fmt.Scanln(&YNQ)
	}
	openfile.Close()
}

其次,让我们尝试理解并回答你的问题。你问道:

为什么fmt.Scanln函数需要一个必需的错误err变量?

  1. Go编译器要求你要么将所有返回值赋给变量,要么不赋给任何变量。你也可以使用占位符_表示你对该变量不感兴趣。请阅读这篇文章获取更多信息:https://gobyexample.com/multiple-return-values。
  2. Scanln返回错误是因为在扫描标准输出时可能会出现错误。

我还需要帮助理解fmt.Writeln函数的参数用途。

fmt包中没有Writeln函数:https://pkg.go.dev/fmt#pkg-index

cannot convert addedText (type int) to type [byte]

请仔细阅读fmt.Scanln函数的文档:https://pkg.go.dev/fmt#Scanln。它不返回文本。它将从stdin读取的内容写入到其参数中。这些参数应该是你想要填充的变量的指针:https://www.geeksforgeeks.org/fmt-scanln-function-in-golang-with-examples/

undefined: openfile

openfile变量确实在此作用域中不可用。请阅读关于Go中作用域的文章:https://medium.com/golangspec/scopes-in-go-a6042bb4298c

这个程序的目的是通过命令行从用户获取输入数据,并将其输出到一个名为go-log.go的文件中。

程序应该像这样:

package main

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

func main() {
	f, err := os.OpenFile("go-log.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()

	YNQ := "yes"
	for YNQ == "yes" {
		fmt.Println("What do you want to add to the log?")

		scanner := bufio.NewScanner(os.Stdin)
		var line string
		if scanner.Scan() {
			line = scanner.Text()
		} else {
			log.Fatalln("Cannot read from stdin.")
		}

		if _, err = f.WriteString(line + "\n"); err != nil {
			log.Fatalln(err)
		}

		fmt.Println("Would you like to add anything else?")
		_, err := fmt.Scanln(&YNQ)
		if err != nil {
			log.Fatalln(err)
		}
	}
}
英文:

First of all, let's make your code readable with the go fmt command:

package main

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

func main() {
	YNQ := &quot;yes&quot;
	for YNQ == &quot;yes&quot; {
		fmt.Println(&quot;What do you want to add to the log?&quot;)
		openfile, err := os.Open(&quot;go-log.txt&quot;)
		addedText, err := fmt.Scanln()
		os.WriteFile(&quot;go-log.txt&quot;, []byte(addedText), 0666)
		//add date and time here
		fmt.Println(&quot;Would you like to add anything else?&quot;)
		fmt.Scanln(&amp;YNQ)
	}
	openfile.Close()
}

Second, let's try to understand and answer your questions. You are asking:
> Why is there is a required error err variable for the fmt.Scanln function?

  1. Go compiler forces you to assign either all return values to variables or none of them. You can also use a placeholder _ marking that you are not interested in this variable. Please, read this article for more information: https://gobyexample.com/multiple-return-values.
  2. Scanln returns the error because there might be an error when you scan a standard output.

> I also need help understanding the purpose of the fmt.Writeln parameters.

There is no function Writeln in the package fmt: https://pkg.go.dev/fmt#pkg-index

> cannot convert addedText (type int) to type [byte]

Please, carefully read the documentation for the fmt.Scanln function: https://pkg.go.dev/fmt#Scanln. It does not return text. It writes what it reads from the stdin to its arguments. These arguments are supposed to be pointers to variables you want to populate: https://www.geeksforgeeks.org/fmt-scanln-function-in-golang-with-examples/

> undefined: openfile

The openfile variable is indeed not available in this scope. Please, read this article about scopes in Go: https://medium.com/golangspec/scopes-in-go-a6042bb4298c

> The purpose of this program is to get input data from the user by the command line and output it to a file go-log.go

The program should look like this:

package main

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

func main() {
	f, err := os.OpenFile(&quot;go-log.txt&quot;, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()

	YNQ := &quot;yes&quot;
	for YNQ == &quot;yes&quot; {
		fmt.Println(&quot;What do you want to add to the log?&quot;)
		
		scanner := bufio.NewScanner(os.Stdin)
		var line string
		if scanner.Scan() {
			line = scanner.Text()
		} else {
			log.Fatalln(&quot;Cannot read from stdin.&quot;)
		}
		
		if _, err = f.WriteString(line + &quot;\n&quot;); err != nil {
			log.Fatalln(err)
		}
		
		fmt.Println(&quot;Would you like to add anything else?&quot;)
		_, err := fmt.Scanln(&amp;YNQ)
		if err != nil {
			log.Fatalln(err)
		}
	}
}

答案2

得分: 1

请参阅其文档:Scanln

该文档提到了Scan,并解释了这些函数返回的内容("成功扫描的项目数")以及为什么会出现错误:

"它返回成功扫描的项目数。如果该数小于要求的数目"

英文:

See its documentation: Scanln

The doc refers to Scan and this explains what the functions return ("the number of items") and why they would error:

"It returns the number of items successfully scanned. If that is less than the number"

huangapple
  • 本文由 发表于 2021年12月31日 09:47:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/70538310.html
匿名

发表评论

匿名网友

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

确定