Go语言实战项目——猜数字(课后作业优化)| 青训营

57 阅读1分钟

很经典的猜数字小游戏

游戏中,程序首先会生成一个 1 到 100 内的随机整数,程序会告诉玩家猜的数字和正确数字相比是大了还是小了,并且让玩家继续猜直到猜对为止。

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	// fmt.Println("The secret number is ", secretNumber)

	fmt.Println("Please input your guess")
	reader := bufio.NewReader(os.Stdin)
	for {
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("An error occured while reading input. Please try again", err)
			continue
		}
		input = strings.Trim(input, "\r\n")

		guess, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid input. Please enter an integer value")
			continue
		}
		fmt.Println("You guess is", guess)
		if guess > secretNumber {
			fmt.Println("Your guess is bigger than the secret number. Please try again")
		} else if guess < secretNumber {
			fmt.Println("Your guess is smaller than the secret number. Please try again")
		} else {
			fmt.Println("Correct, you Legend!")
			break
		}
	}
}

原项目的输入是采用bufio包

在Go语言中,bufio包实现了带缓冲的I/O操作,它封装了os.File对象,提供了在文件读取和写入时添加缓冲的功能。主要特点有:

  • 读取时会批量读取到缓冲区,可以少量多次读入。
  • 写入时会缓冲数据,只有缓冲区写满时才会flush到文件,减少了IO操作次数。
  • 支持按行读取,非常方便。
  • 性能高,减少了系统调用开销。

使用bufio包和fmt.Scanf读取输入主要有以下几点区别:

  1. bufio通过缓冲区实现了对文件或stdin的优化批量读取,而fmt.Scanf是非缓冲直接读取,每次都发生系统调用。
  2. bufio可以按行读取输入,而fmt.Scanf是Format参数格式化读取。
  3. bufio可以灵活控制每次读取的数据量,而fmt.Scanf每次只读取符合一Format所解析的数据。
  4. bufio主要用于文件,也可用于stdin;fmt.Scanf主要用于stdin。
  5. bufio返回读取的字节数和错误;fmt.Scanf返回成功解析的参数个数和错误。
  6. bufio的读取需要自己转换类型,fmt.Scanf可以直接解析为指定类型。
  7. bufio可以自定义缓冲区大小,fmt.Scanf使用默认值。

总之,bufio更灵活,可以优化IO性能, fmt.Scanf更简单,便于直接读取为指定类型。我们可以根据不同场景选择使用。 课后作业需要我们用fmt.Scanf来简化代码:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	// fmt.Println("The secret number is ", secretNumber)
	fmt.Println("Please input your guess")
	var guess int
	for {
		fmt.Scan(&guess)
		if guess < 0 || guess > 100 {
			fmt.Println("The secret number is between 0~100, please try again")
			continue
		} else if guess > secretNumber {
			fmt.Println("Your guess is bigger than the secret number. Please try again")
		} else if guess < secretNumber {
			fmt.Println("Your guess is smaller than the secret number. Please try again")
		} else {
			fmt.Println("Correct, you Legend!")
			break
		}
	}
}