对比学习 Go 和 Rust:猜数字游戏

2022年1月5日 // Go Rust 编程

在官方的Rust 程序设计语言一书中,在第 2 章专门详细介绍了一个猜数字游戏。本章再次列出该程序代码,同时用 Go 实现相同的程序,为的是通过对比,能初步了解两种语言的异同。

Rust

Rust 程序设计语言中的猜数字游戏

use rand::Rng;
use std::cmp::Ordering;
use std::io;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1..101);

    loop {
        println!("Please input your guess.");

        let mut guess = String::new();

        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read line");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}

Go

以下是用 Go 实现的猜数字游戏的构建过程。

$ mkdir guessinggame
$ cd guessinggame
$ touch main.go
$ go mod init example.com/guessinggame

这样在 guessinggame 目录将存在两个文件,main.gogo.mod,其中 go.mod 文件的内容如下:

module example.com/guessinggame

go 1.17

接下来就是在 main.go 文件中写代码了,这里直接填写最终的代码:

package main

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

func main() {
	fmt.Println("Guess the number!")

	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(101)

Loop:
	for {
		fmt.Println("Please input your guess.")
		guess := -1

		_, err := fmt.Scanln(&guess)
		if err != nil {
			fmt.Println("Failed to read line:", err)
			continue
		}

		fmt.Printf("You win: %v\n", guess)

		switch {
		case guess < secretNumber:
			fmt.Println("Too small!")
		case guess > secretNumber:
			fmt.Println("Too big!")
		case guess == secretNumber:
			fmt.Println("You win!")
			break Loop
		}
	}
}

其实即便是这种简单的程序,前面的 Rust 和后面的 Go 的表现也不完全一样。你可以在一行中同时输入用空格分隔的两个数字看看情况,或者输入非数字试试。