用一个控制台程序学习Rust

我们将会用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以来做的第一个实例()

rust
189 views
Comments
登录后评论
Sign In