溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

發(fā)布時間:2021-10-19 16:24:14 來源:億速云 閱讀:144 作者:iii 欄目:編程語言

這篇文章主要講解了“Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程”吧!

Rust如何管理項目

并不是所有的代碼都像hello_world.rs一樣,一個文件就可以搞定。一個項目往往具有復(fù)雜的代碼,我們需要一種機制來管理這種復(fù)雜性,將一個項目切分成若干小部分,每個部分再進(jìn)行切分,層層抽象,直到達(dá)到人腦可以處理的規(guī)模。每種編程語言都有這樣的機制,例如Java的package機制,Rust也不例外。

Rust用了兩個概念來管理項目:一個是crate(項目),一個是mod(模塊)。模塊是用于在crate內(nèi)部進(jìn)行分層和封裝的機制,模塊內(nèi)部可以包含模塊。

  • crate:可以簡單理解為一個項目,crate是Rust中的獨立編譯單元(compile unit),每個crate對應(yīng)生成一個庫或者可執(zhí)行文件。作為對比,我們比較熟悉的C語言中,一個單獨的.c文件和其所有的include文件組成一個編譯單元,每個.c生成一個.o,然后將這些.o鏈接起來生成可執(zhí)行文件。

  • mod:可以簡單理解為命名空間。mod可以嵌套(注意crate之間不能出現(xiàn)循環(huán)引用),還可以控制內(nèi)部元素的可見性。

說到可見性問題,在Rust中,元素默認(rèn)都是私有的,用pub關(guān)鍵字修飾的才是公開的。公開和私有的訪問權(quán)限規(guī)定如下:

  • 如果一個元素是私有的,那么只有本模塊內(nèi)的元素以及它的子模塊可以訪問

  • 如果一個元素是公開的,那么可以在本模塊外的作用域訪問它。

模塊是一種抽象的概念,文件是承載這個概念的實體,但是模塊和文件并不是簡單的一一對應(yīng)關(guān)系。在一個crate內(nèi)部創(chuàng)建mod的方式有下面三種:

  • 在一個rs文件中創(chuàng)建內(nèi)嵌模塊,直接使用mod關(guān)鍵字即可。

  • 獨立的一個rs文件就是一個模塊,文件名即是模塊名。

  • 一個文件夾也可以創(chuàng)建一個模塊,文件夾內(nèi)部要有一個xxx.rs文件,這個文件是這個模塊的入口。必須要在這個xxx.rs中聲明其子模塊,否則子模塊無法被當(dāng)成這個項目的源碼進(jìn)行編譯。

新建項目

cargo不僅是Rust的包管理器,還可以用于創(chuàng)建項目。使用下列命令可以創(chuàng)建一個名為guessing_game的項目:

cargo new guessing_game --bin

注意,后面的--bin意味著我們希望項目生成的是可執(zhí)行程序,如果希望是library,則可以使用--lib選項。

以上為在命令行中手工創(chuàng)建項目,在Clion中可以點擊File->New Project后如下圖填寫,然后點擊Create按鈕:

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

項目結(jié)構(gòu)

我們可以使用tree .命令或者直接在Clion中查看當(dāng)前的文件夾結(jié)構(gòu),如下圖所示:

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

  • src/main.rs:這是cargo自動生成的rs文件。還記得前面講的crate和mod的概念嗎?在這個項目中,guessing_game是crate,src文件夾是mod,main.rssrcmod的入口。我們可以在srcmod中創(chuàng)建子模塊,但注意,這些子模塊都要在main.rs中聲明,否則無法參與編譯。

  • .gitignore:這是git忽略文件,不懂其作用的同學(xué)可以自行搜索。這里重點要說的是通過cargo new創(chuàng)建的項目天然就是一個git項目,這也印證了Rust對開源的擁護(hù)。

  • Cargo.toml:這是項目管理配置文件。TOML是一種非常簡潔好用的配置文件格式,TOML是Tom's Obvious, Minimal Language的首字母縮寫,這里的Tom是Github的聯(lián)合創(chuàng)始人之一,感興趣的同學(xué)可以進(jìn)一步自行了解TOML配置文件的寫法。

  • Cargo.lock:該文件包含項目依賴項的確切信息,由Cargo維護(hù),我們無須關(guān)心它。

編譯執(zhí)行

src/main.rs里cargo已經(jīng)自動生成了輸出Hello, world!的代碼,我們來運行一下它看能否正常輸出。

插一句題外話,在你日后漫長的Rust編碼生涯中,你會發(fā)現(xiàn),你將在處理編譯錯誤上耗費大量的時間。還記得嗎,Rust 的一大特色是保證內(nèi)存安全,這保證了Rust代碼只要運行起來就幾乎不會發(fā)生內(nèi)存錯誤,這么誘人的效果的背后的代價就是,我們要在編碼時付出額外的努力。Rust為了保證內(nèi)存安全設(shè)計了一套復(fù)雜的規(guī)則,這導(dǎo)致我們的代碼一不留神就會編譯不過。所以,在你日后經(jīng)常用的一個操作就是檢查能否編譯通過,而不是直接編譯,因為直接編譯還要做代碼優(yōu)化等會相對費時。可以使用下列命令檢查編譯錯誤:

cargo check

在Clion中需要新加一個Configuration來執(zhí)行cargo check命令,如下圖所示:

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

確保cargo check通過后,可以執(zhí)行cargo build來執(zhí)行編譯。編譯后會產(chǎn)生一個target文件夾,在target/debug下會有一個和crate同名的可執(zhí)行文件。但一般為了方便,可以直接執(zhí)行cargo run,這條命令等價于先編譯后執(zhí)行。下圖是執(zhí)行cargo run后Clion的控制臺輸出:

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

猜謎游戲

在完成了項目搭建后,接下來就要開始猜謎游戲的代碼編寫了,我將它們分成六部分:創(chuàng)建變量、輸入、輸出、錯誤處理、隨機數(shù)生成、完整代碼。

創(chuàng)建變量

使用let語句創(chuàng)建變量,需要注意的是,在Rust中,變量默認(rèn)是不可變的,可以在變量名前使用mut來使得變量可變:

let a = 5; // 不可變
let mut b = 10; // 可變

在上面的let語句中,我們并沒有顯示聲明變量的類型,但這并不代表Rust是動態(tài)類型的,Rust仍然是靜態(tài)類型的,只不過Rust有一個可以通過上下文推斷類型的強大編譯器。

輸出

我們早已在hello_world.rs中見識過了最基本的輸出方式:

println!("Hello, world!");

需要注意的是,這里的println!是一個宏,而非一個函數(shù),println后面的感嘆號就是宏的標(biāo)志。Rust中的宏與C/C++中的宏是完全不一樣的東西,簡單說,可以把它理解為一種安全版的編譯期語法擴展。這里之所以使用輸出宏而非函數(shù),是因為標(biāo)準(zhǔn)輸出宏可以完成編譯期格式檢查,更加安全。

如果需要輸出某個變量的值,可以使用占位符{},例如:

let x = 0;
let y = 10;
println!("x = {} and y = {}", x, y);

其輸出結(jié)果為:

x = 0 and y = 10
輸入

為了從控制臺中獲取用戶的輸入,需要使用標(biāo)準(zhǔn)庫std::io。使用use語句將該庫引入當(dāng)前作用域:

use std::io;

我們可以使用io庫中的函數(shù)stdin

let mut guess = String::new(); // 創(chuàng)建一個字符串類型的可變變量
io::stdin().read_line(&mut guess).expect("Failed to read line");

stdin函數(shù)返回一個std::io::Stdin的實例,這代表終端標(biāo)準(zhǔn)輸入句柄的類型。然后調(diào)用read_line方法,可以從標(biāo)準(zhǔn)輸入中讀取一行并存入到guess變量中去。&表示這是一個引用,這是一個復(fù)雜的特性,我們現(xiàn)在無須了解它。

讀取用戶輸入后,我們需要判斷用戶是否正確輸入了數(shù)字。String類型帶有處理字符串處理的一些方法:

let guess: u32 = guess.trim().parse().expect("Please type a number!");

字符串的 parse 方法將字符串解析成數(shù)字。因為這個方法可以解析多種數(shù)字類型,因此需要告訴 Rust 具體的數(shù)字類型,這里通過 let guess: u32 指定。guess 后的冒號:告訴 Rust 我們指定了變量的類型。Rust 有一些內(nèi)建的數(shù)字類型,u32 是一個無符號的 32 位整型。trim方法用于消除回車空格等符號。

錯誤處理

上一小節(jié)代碼中還有一個expect沒有分析,而這就涉及到Rust中的錯誤處理機制了。read_line的返回值類型是io::Result,它是Result類型在io模塊的特化版本。Result是枚舉類型,其成員為OkErr,Ok 成員表示操作成功,內(nèi)部包含成功時產(chǎn)生的值。Err 成員則意味著操作失敗,并且包含失敗的前因后果。

Result類型的作用是編碼錯誤處理信息。Result 類型像其他類型一樣,擁有定義于其上的方法。io::Result的實例擁有expect方法。如果 io::Result 實例的值是 Err,expect 會導(dǎo)致程序崩潰,并打印參數(shù)傳遞給 expect 的信息。如果io::Result實例的值是 Ok,expect 會獲取 Ok 中的值并返回。在本例中,這個值是用戶輸入到標(biāo)準(zhǔn)輸入中的字節(jié)數(shù)。

隨機數(shù)生成

猜謎游戲需要能夠自動生成隨機數(shù)。Rust標(biāo)準(zhǔn)庫中尚未包含隨機數(shù)功能,但我們可以通過引入外部crate來獲得隨機數(shù)功能。還記得Rust的官方開源倉庫嗎,那里可是有很多寶貝的。打開https://crates.io/,在搜索框中鍵入rand來搜索具有隨機數(shù)功能的crate,出來的第一個結(jié)果就是我們需要的crate。

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

現(xiàn)在我們將這個庫引入到我們的項目中。打開Cargo.toml,在[dependencies]下添加:

[dependencies]

rand = "0.8.3"

[dependencies] 告訴 Cargo 本項目依賴了哪些外部 crate 及其版本。

下面使用rand庫來產(chǎn)生隨機數(shù)。首先,使用use語句引入randuse rand::Rng;。然后調(diào)用下列函數(shù)產(chǎn)生一個1和100之間的數(shù):

let number = rand::thread_rng().gen_range(1..=100);
完整代碼

猜謎游戲的完整代碼如下。

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

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

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

    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;
            }
        }
    }
}

其中,涉及控制流操作的loop、match、continue、break等語法,大家應(yīng)當(dāng)能夠望文生義。對于這個完整代碼,大家能夠閱讀并知道每一行干了啥即可,不必糾結(jié)于語法細(xì)節(jié)。

猜謎游戲運行結(jié)果如下:

Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程

感謝各位的閱讀,以上就是“Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Rust學(xué)習(xí)筆記之實現(xiàn)一個猜謎游戲小項目的方法教程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI