我們將會用 Rust 做一個波蘭表達式的簡單控制台程序,支持浮點數和負數。
從控制台輸入#
在 Rust 裡,獲取控制台輸入很簡單,標準庫env
中提供了方式讓我們方便的獲取控制台輸入。
let symbol:String = env::args()
//輸入的第幾個
.nth(1)
// 簡單的錯誤處理
.expect("輸入不完整");
let var_a:String = env::args().nth(2).expect("輸入不完整");
let var_b:String = env::args().nth(3).expect("輸入不完整");
println!("|{}|{}|{}|", symbol, var_a, var_b);
然後,讓我們運行一下看看
cargo run -- 1 2 3
沒問題的話,你會發現控制台輸出了
|1|2|3|
此時的代碼:
use std::env;
// 基礎的獲取控制台輸入
fn obtain_var() {
// 希望獲取的值
let symbol:String = env::args().nth(1).expect("輸入不完整");
let var_a:String = env::args().nth(2).expect("輸入不完整");
let var_b:String = env::args().nth(3).expect("輸入不完整");
println!("|{}|{}|{}|", symbol, var_a, var_b);
}
fn main() {
obtain_var();
}
但這是不夠的,我們還需要把得到的數據傳入計算模塊,裡面就涉及了 ---- 類型轉換
類型轉換#
為了確保我們的控制台應用有一定的可用性,我們支持小數和負數。數字類型需要轉換到f64
,也就是浮點數。
// 轉換類型
fn change_type(var:String) -> f64 {
let var:f64 = match var.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("錯誤:非法輸入");
// Err退出
return 0.0;
}
};
// 返回轉換完成的值
var
}
下一步,我們要找一個方法存儲我們轉換的類型,我在這裡選用了數組
來進行存儲。
目前的代碼:
// 獲取控制台輸入
fn obtain_var() {
// 希望獲取的值
let symbol:String = env::args().nth(1).expect("輸入不完整");
let var_a:String = env::args().nth(2).expect("輸入不完整");
let var_b:String = env::args().nth(3).expect("輸入不完整");
// 轉換類型存入數組方便管理
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
...
我們還需要一個方法存儲我們得到的值,這裡我選用了結構體:
首先 在程序頭部聲明結構體
...
// 使用結構體存入數據
struct ComputeData {
symbol:String,
var_a:f64,
var_b:f64
}
...
然後,我們設定這個函數返回一個結構體,方便我們調用。
並且,創造一個結構體供我們返回值
// 獲取控制台輸入
fn obtain_var() -> ComputeData {
// 希望獲取的值
let symbol:String = env::args().nth(1).expect("輸入不完整");
let var_a:String = env::args().nth(2).expect("輸入不完整");
let var_b:String = env::args().nth(3).expect("輸入不完整");
// 轉換類型存入數組方便管理
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
// 將數據存入結構體
let data = ComputeData {
symbol:String::from(symbol),
var_a:number_var[0],
var_b:number_var[1]
};
// 函數返回一個結構體
data
}
好啦,接下來我們就可以寫一個計算函數了。
計算#
輸入進來的數據和返回結果
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64
按理來說,我們現在只需要用一個match
判斷然後返回值就好,但是在 Rust 裡,match 是不能直接檢查String
類型的,我們還需要轉換成&str
類型
完整代碼:
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64 {
// 使用切片的引用模式 將symbol轉換為`&str`
let symbol:&str = &symbol.to_string()[..];
match symbol {
"+" => var_a + var_b,
"-" => var_a - var_b,
"*" => var_a * var_b,
"/" => var_a / var_b,
// 錯誤處理
_ => {
println!("非法的計算符號");
// 返回`0.0`表示出錯
0.0
}
}
}
完成啦!#
接下來寫個main
就好了~
// 優化了可讀性
fn main() {
println!("{}",compute(
obtain_var().symbol,
obtain_var().var_a,
obtain_var().var_b
)
);
}
運行#
cargo run -- 運算符 數字1 數字2
例如
cargo run -- / 2 5
在終端運行結果 返回值 -> 0.4
完整代碼#
use std::env;
// 使用結構體存入數據
struct ComputeData {
symbol:String,
var_a:f64,
var_b:f64
}
fn main() {
println!("{}",compute(
obtain_var().symbol,
obtain_var().var_a,
obtain_var().var_b
)
);
}
// 獲取控制台輸入
fn obtain_var() -> ComputeData {
// 希望獲取的值
let symbol:String = env::args().nth(1).expect("輸入不完整");
let var_a:String = env::args().nth(2).expect("輸入不完整");
let var_b:String = env::args().nth(3).expect("輸入不完整");
// 轉換類型存入數組方便管理
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
// 將數據存入結構體
let data = ComputeData {
symbol:String::from(symbol),
var_a:number_var[0],
var_b:number_var[1]
};
// 函數返回一個結構體
data
}
// 轉換類型
fn change_type(var:String) -> f64 {
let var:f64 = match var.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("錯誤:非法輸入");
// Err退出
return 0.0;
}
};
// 返回轉換完成的值
var
}
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64 {
// 使用切片的引用模式 將symbol轉換為`&str`
let symbol:&str = &symbol.to_string()[..];
match symbol {
"+" => var_a + var_b,
"-" => var_a - var_b,
"*" => var_a * var_b,
"/" => var_a / var_b,
// 錯誤處理
_ => {
println!("非法的計算符號");
// 返回`0.0`表示出錯
0.0
}
}
}
這其實也是我學 Rust 以來做的第一個實例()