Rust
Hello, Rust
fn main() {
println!("Hello, Rust!");
}
println!
調用了一個 Rust 宏(macro)而不是普通函數;
如果是調用函數,則應輸入println
(沒有!)。- Rust 習慣以分號
;
結尾。 .rs
文件的編譯和運行是獨立的步驟(與 C/C++ 類似)
先編譯rustc main.rs
,再運行.\main.exe
(Windows 下)
Hello, Cargo
Cargo 是 Rust 的構建系統和包管理器,cargo --version
查看版本號。
cargo 生成項目
讓我們使用 Cargo 生成一個 hello_cargo 的項目:
$ cargo new hello_cargo # 新建了名爲 hello_cargo 的目錄, 同時 Cargo 在其中創建項目文件
$ cd hello_cargo
目錄結構:src 包下存放代碼
hello_cargo
|--- src
|--- Cargo.toml
|--- .gitignore
用文本編輯器打開 Cargo.toml
:
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["szluyu99 <[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[package]
,是一個片段(section)標題,表明下面的語句用來配置一個包,接下來四行配置了 項目名、版本、作者 以及 要使用的 Rust 版本。
[dependencies]
,是羅列項目依賴的片段的開始,在 Rust 中,代碼包被稱爲 crates
。
cargo build 構建項目,再運行項目
在 hello_cargo 目錄下使用 cargo build
構建項目:
$ cargo build
Compiling hello_cargo v0.1.0 (D:\CodePro\Rust\hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.68s
這個命令會創建一個可執行文件 target\debug\hello_cargo.exe
,而不是放在目前目錄下。
可以通過這個命令運行可執行文件: .\target\debug\hello_cargo.exe
。
cargo run 編譯並運行項目
上面使用了 cargo build
構建了項目,並使用了 .\target\debug\hello_cargo.exe
運行了項目。
也可以使用 cargo run
在一個命令中 同時編譯並運行生成的可執行文件:
由於前面已經編譯過,並且代碼沒有修改,所以這次無需編譯直接運行:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running `target\debug\hello_cargo.exe`
Hello, world!
如果修改了 main.rs 中的代碼,則需要重新編譯運行:
$ cargo run
Compiling hello_cargo v0.1.0 (D:\CodePro\Rust\hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.44s
Running `target\debug\hello_cargo.exe`
Hello, world!!
cargo check 編譯並檢查項目(不生成可執行文件)
Cargo 還提供了一個叫 cargo check
的命令;該命令快速檢查代碼確保其可以編譯,但並不產生可執行文件。
$ cargo check
Checking hello_cargo v0.1.0 (D:\CodePro\Rust\hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.15s
通常 cargo check
要比 cargo build
快得多,因爲它省略了生成可執行文件的步驟。建議定期運行 cargo check
確保代碼可以編譯,當準備好使用可執行文件時才運行 cargo build
。
總結:
- 可以使用
cargo build
或cargo check
構建項目。 - 可以使用
cargo run
一步構建並運行項目。 - 有別於將構建結果放在與源碼相同的目錄,Cargo 會將其放到
target/debug
目錄。
發佈項目
發佈(Release)構建
- 當項目最終準備好發佈時,可以使用
cargo build --release
來優化編譯項目。這會在target/release
而不是target/debug
下生成可執行文件。 - 這些優化可以讓 Rust 代碼運行的更快,不過啓用這些優化也需要消耗更長的編譯時間。這也就是爲什麼會有兩種不同的配置:一種是爲了開發,你需要經常快速重新構建;另一種是爲用戶構建最終程序,它們不會經常重新構建,並且希望程序運行得越快越好。
- 如果你在測試代碼的運行時間,請確保運行
cargo build --release
並使用target/release
下的可執行文件進行測試。
“猜猜看” 遊戲
“猜猜看” 介紹:
- 程序將會隨機生成一個 1 到 100 之間的隨機整數。
- 接着它會請玩家猜一個數並輸入,然後提示猜測是大了還是小了。
- 如果猜對了,它會打印祝賀信息並退出。
創建一個新項目:
$ cargo new guessing_game
$ cd guessing_game
在 src/main.rs
中開始編寫我們的代碼。
處理一次猜測
獲取用戶猜測並打印的代碼:
use std::io;
fn main() {
println!("Guess the number!");
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("Failed to read line!");
println!("You guessed: {}", guess );
}
爲了獲取用戶輸入並打印結果作爲輸出,我們需要將 io
(輸入/輸出)庫引入當前作用域。
io
庫來自於標準庫(也被稱爲 std
):
use std::io;
let 語句,用來創建 變量,Rust 中,變量默認不可變,利用 mut
創建 可變變量。
let foo = 5; // 不可變
let mut bar = 5; // 可變
::new
那一行的 ::
語法表明 new
是 String
類型的一個 關聯函數(associated function)。關聯函數是針對類型實現的,在這個例子中是 String,而不是 String 的某個特定實例。一些語言中把它稱爲 靜態方法(static method)。
let mut guess = String::new();
創建了一個可變變量並綁定到一個新的 String
空實例上。
io::stdin().read_line(&mut guess).expect("Failed to read line!");
stdin
函數返回一個 std::io::Stdin
的實例,這代表終端標準輸入句柄的類型。
.read_line(&mut guess)
調用 read_line
方法從標準輸入句柄獲取用戶輸入。
&
表示這個參數是一個 引用(reference),它允許多處代碼訪問同一處數據,而無需在內存中多次拷貝。引用默認是不可變的,需要寫成 &mut guess
來使其可變,而不是 &guess
。
read_line
將用戶輸入附加到傳遞給它的字符串中,不過它也返回一個值 —— 在這個例子中是 io::Result
。Rust 標準庫中有很多叫做 Result
的類型:一個通用的 Result 以及在子模塊中的特化版本,比如 io::Result
。
Result
類型是 枚舉(enumerations),通常也寫作 enums
。枚舉類型持有固定集合的值,這些值被稱爲枚舉的 成員(variants)。
Result
的成員是 Ok
和 Err
,Ok
成員表示操作成功,內部包含成功時產生的值。Err
成員則意味着操作失敗,並且包含失敗的前因後果。
如果不調用 expect
,程序也能編譯,不過會出現一個警告:
$ cargo build
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
warning: unused `std::result::Result` which must be used
--> src/main.rs:10:5
|
10 | io::stdin().read_line(&mut guess);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
消除警告的正確做法是實際編寫錯誤處理代碼,不過由於我們就是希望程序在出現問題時立即崩潰,所以直接使用 expect
。
測試代碼運行:
$ cargo run
Compiling guessing_game v0.1.0 (D:\CodePro\Rust\guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 0.81s
Running `target\debug\guessing_game.exe`
Guess the number!
Please input your guess.
1231
You guessed: 1231
生成一個隨機數
Rust 標準庫中尚未包含隨機數功能。然而,Rust 團隊還是提供了一個 rand crate
。
修改 Cargo.toml 文件,引入一個 rand 依賴:
[dependencies]
rand = "0.5.5"
開始編寫生成一個隨機數功能的代碼:
use std::io;
use rand::Rng;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1, 101);
println!("The secret number is: {}", secret_number);
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
println!("You guessed: {}", guess);
}
有空繼續學。。。。