中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

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

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

Rust如何管理項目

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

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

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

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

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

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

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

模塊是一種抽象的概念,文件是承載這個概念的實體,但是模塊和文件并不是簡單的一一對應關系。在一個crate內部創建mod的方式有下面三種:

  • 在一個rs文件中創建內嵌模塊,直接使用mod關鍵字即可。

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

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

新建項目

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

cargo new guessing_game --bin

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

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

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

項目結構

我們可以使用tree .命令或者直接在Clion中查看當前的文件夾結構,如下圖所示:

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

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

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

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

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

編譯執行

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

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

cargo check

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

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

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

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

猜謎游戲

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

創建變量

使用let語句創建變量,需要注意的是,在Rust中,變量默認是不可變的,可以在變量名前使用mut來使得變量可變:

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

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

輸出

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

println!("Hello, world!");

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

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

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

其輸出結果為:

x = 0 and y = 10
輸入

為了從控制臺中獲取用戶的輸入,需要使用標準庫std::io。使用use語句將該庫引入當前作用域:

use std::io;

我們可以使用io庫中的函數stdin

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

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

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

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

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

錯誤處理

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

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

隨機數生成

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

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

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

[dependencies]

rand = "0.8.3"

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

下面使用rand庫來產生隨機數。首先,使用use語句引入randuse rand::Rng;。然后調用下列函數產生一個1和100之間的數:

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

其中,涉及控制流操作的loopmatchcontinuebreak等語法,大家應當能夠望文生義。對于這個完整代碼,大家能夠閱讀并知道每一行干了啥即可,不必糾結于語法細節。

猜謎游戲運行結果如下:

Rust學習筆記之實現一個猜謎游戲小項目的方法教程

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大姚县| 水城县| 余江县| 蓝山县| 丘北县| 白银市| 青海省| 水城县| 桐乡市| 东乡| 东明县| 康保县| 两当县| 金堂县| 汾阳市| 巩义市| 孝感市| 日喀则市| 绥芬河市| 新津县| 廉江市| 兴文县| 泰来县| 介休市| 阜城县| 红桥区| 丰镇市| 陇西县| 措美县| 随州市| 张家港市| 恭城| 嵩明县| 民县| 唐海县| 那曲县| 崇阳县| 竹北市| 虞城县| 滦平县| 泰州市|