Golang中处理用户输入为什么这么难!

Golang中处理用户输入为什么这么难! 我刚开始学习Go语言时心态很好,但尽管它被称为简洁的语言,光是获取用户输入就有很多种方式,而且都让人困惑。

我可能只是固守了从其他语言带来的观念,虽然在学习Go之前被告知不要这样,但即便如此,在一个现代语言中,为什么需要输入4-5行代码才能获取用户输入呢?

请帮我检查一下我的代码,并且能否优化它?这是使用 bufio 输入数组的代码。我才刚开始学习两天,请多包涵。

// input function
func getInput(prompt string, r *bufio.Reader) (string, error) {
	fmt.Println(prompt)
	input, err := r.ReadString('\n')
	if err != nil {
		log.Fatal("Error while reading input!")
	}
	return strings.TrimSpace(input), err
}

// main function
func main() {
	reader := bufio.NewReader(os.Stdin)              // Reader
	input, _ := getInput("Enter the size: ", reader) // Get Input function
	size, _ := strconv.Atoi(input)                   // Parse string to input

	var arr []int // decclare a slice
	for i := 0; i < size; i++ {
		var x int
		fmt.Scanf("%d", &x)
		arr = append(arr, x)
	}
	fmt.Println(arr)
}

更多关于Golang中处理用户输入为什么这么难!的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

现在我明白了。我确实误解了Go语言中“简单”的含义。我原以为它指的是一种语法简短直接的语言。

不过,你的帖子确实很有道理。

更多关于Golang中处理用户输入为什么这么难!的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我刚开始以良好的心态学习Go语言,但尽管它被称为简洁的语言,仅仅获取用户输入就有很多种方法,而且它们都令人困惑。

我不确定这是否适用于你的情况,但如果你使用网页表单,你可以使用JavaScript从表单获取输入。

var myForm = document.getElementById('form');
myForm.addEventListener('submit', function(event) {
  var formData = new FormData(myForm)
  var object = {};
  formData.forEach(function(value, key) {
    object[key] = value;
  });
  var json = JSON.stringify(object)
  alert(json)
});

输出结果是JSON,你可以在Go和JavaScript中处理它。

为什么在现代编程语言中,用户输入需要写4-5行代码。

我猜你指的是 getInput 函数。为了简洁起见,并且忽略错误处理(就像许多语言习惯做的那样),你可以像这样从 stdin 读取输入:

var value string
fmt.Scanln(&value)

但是,让我们看看你在 getInput 函数中做了什么,并加上一些注释:

func getInput(prompt string, r *bufio.Reader) (string, error) {
	// 向用户显示提示信息(这与读取输入无关)
	fmt.Println(prompt)
	// 读取输入
	input, err := r.ReadString('\n')
	// 如果出现错误,处理它。
	if err != nil {
		log.Fatal("Error while reading input!")
	}
	// 修剪输入并返回
	return strings.TrimSpace(input), err
}

你做的事情不止一件;每件事或多或少都有自己的代码行。这有什么不好呢?或者,你能解释一下你觉得哪部分令人困惑或不简单吗?因为在我看来这很简单。

话虽如此,我认为在这种情况下“简单”这个词有点复杂。编写软件几乎从来都不简单。就 Go 语言而言,我认为人们使用这个词是因为 Go 语言有自己的设计理念,没有太多的语言冗余,这鼓励了简单的库/框架和极快的编译时间。但它的简单之处并不在于使用魔法将细节抽象掉。你必须知道自己在做什么,并且有意识地去做。你还必须处理错误,或者有意识地不去处理它们。

你的代码已经很好地使用了bufio.Reader来获取用户输入,这是处理输入的一种高效方式。不过,在循环中使用fmt.Scanf可能会导致输入缓冲区的问题,尤其是当混合使用bufio.Readerfmt.Scanf时。下面是一个优化版本,统一使用bufio.Reader来处理所有输入,并改进错误处理:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func getInput(prompt string, r *bufio.Reader) (string, error) {
	fmt.Print(prompt)
	input, err := r.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(input), nil
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 获取数组大小
	input, err := getInput("Enter the size: ", reader)
	if err != nil {
		fmt.Println("Error reading size:", err)
		return
	}

	size, err := strconv.Atoi(input)
	if err != nil {
		fmt.Println("Invalid size:", err)
		return
	}

	// 获取数组元素
	arr := make([]int, 0, size)
	for i := 0; i < size; i++ {
		input, err := getInput(fmt.Sprintf("Enter element %d: ", i+1), reader)
		if err != nil {
			fmt.Println("Error reading element:", err)
			return
		}

		num, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid number:", err)
			return
		}
		arr = append(arr, num)
	}

	fmt.Println("Array:", arr)
}

这个版本的主要改进:

  1. 统一使用bufio.Reader读取所有输入,避免缓冲区冲突
  2. 使用fmt.Print代替fmt.Println,让提示和输入在同一行
  3. 更完整的错误处理,而不是直接调用log.Fatal
  4. 为切片预分配容量以提高性能

如果你想要更简洁的版本,可以使用fmt.Scanln,但要注意它对于包含空格的输入处理不如bufio灵活:

package main

import "fmt"

func main() {
	var size int
	fmt.Print("Enter the size: ")
	fmt.Scanln(&size)

	arr := make([]int, size)
	for i := 0; i < size; i++ {
		fmt.Printf("Enter element %d: ", i+1)
		fmt.Scanln(&arr[i])
	}

	fmt.Println("Array:", arr)
}

Go语言处理输入的方式确实多样,但这也提供了灵活性。bufio适合需要精细控制输入的场景,而fmt.Scan系列函数适合简单的交互式输入。

回到顶部