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

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

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

Rust

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

cargo new guessing_game
cd guessing_game
echo 'rand = "0.9.0"' >> Cargo.toml
code src/main.rs
cargo run

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
code main.go
go run .

这样在 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 的表现也不完全一样。你可以在一行中同时输入用空格分隔的两个数字看看情况,或者输入非数字试试。