我们将会用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
判断然后返回值就好,但是在Rsut里,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
}
}
}
这其实也是我学Rsut以来做的第一个实例()