使用 Rust 编写简单计算器

发布于:2025-06-24 ⋅ 阅读:(22) ⋅ 点赞:(0)

在编程语言的世界中,Rust 以其安全性和高性能而闻名。今天,我们将通过一个简单的项目来探索 Rust 的魅力 —— 编写一个简单的命令行计算器。这个计算器将支持基本的算术运算(加、减、乘、除),并且可以通过用户输入进行交互。

完整代码

以下是完整的 Rust 代码,用于实现一个简单的命令行计算器。代码中包含了详细的注释,帮助你理解每个部分的功能。

use std::io;
use std::io::Write;

fn main() {
    // 创建一个 UserTyper 实例,使用 CommandLineComputer 作为计算机
    let mut typer = UserTyper::new(CommandLineComputer);
    loop {
        // 提示用户输入表达式
        typer.type_expr();
        // 如果用户输入了 "q",则退出程序
        if typer.expr.contains("q") {
            break;
        }
        // 计算并打印结果
        println!("Result:{}", typer.compute());
    }
}

// 定义一个计算机 trait,所有计算机都必须实现这个 trait
trait Computer {
    fn compute(&self, expr: &str) -> i32;
}

// 实现一个简单的命令行计算机
struct CommandLineComputer;

// 为 CommandLineComputer 实现 Computer trait
impl Computer for CommandLineComputer {
    fn compute(&self, expr: &str) -> i32 {
        // 初始化两个数字和一个操作符
        let mut num1 = String::new();
        let mut num2 = String::new();
        let mut op: Option<char> = None;

        // 遍历表达式中的每个字符
        for chr in expr.trim().chars() {
            if chr.is_digit(10) {
                // 如果是数字,根据操作符是否已确定,将数字添加到 num1 或 num2
                if op.is_none() {
                    num1.push(chr);
                } else {
                    num2.push(chr);
                }
                continue;
            }
            // 匹配操作符
            match chr {
                '+' | '-' | '*' | '/' if op.is_none() => op = Some(chr),
                _ if chr.is_whitespace() => continue,
                _ => panic!("Invalid character: {}", chr),
            }
        }

        // 检查表达式是否有效
        if num1.is_empty() || num2.is_empty() || op.is_none() {
            panic!("Invalid expression: {}", expr);
        }

        // 将字符串转换为数字
        let num1: i32 = num1.parse().unwrap();
        let num2: i32 = num2.parse().unwrap();
        let op: char = op.unwrap();

        // 根据操作符进行计算
        match op {
            '+' => num1 + num2,
            '-' => num1 - num2,
            '*' => num1 * num2,
            '/' => num1 / num2,
            _ => unreachable!(),
        }
    }
}

// 定义一个用户输入处理结构
struct UserTyper<T: Computer> {
    computer: T,
    expr: String,
}

// 为 UserTyper 实现方法
impl<T: Computer> UserTyper<T> {
    // 创建一个新的 UserTyper 实例
    fn new(computer: T) -> Self {
        Self {
            computer,
            expr: String::new(),
        }
    }

    // 提示用户输入表达式
    fn type_expr(&mut self) {
        self.expr.clear();
        print!("Please type an expression: ");
        io::stdout().flush().unwrap();
        io::stdin()
            .read_line(&mut self.expr)
            .expect("Failed to read line");
    }

    // 调用计算机进行计算
    fn compute(&self) -> i32 {
        self.computer.compute(&self.expr)
    }
}

代码讲解

主函数

fn main() {
    let mut typer = UserTyper::new(CommandLineComputer);
    loop {
        typer.type_expr();
        if typer.expr.contains("q") {
            break;
        }
        println!("Result:{}", typer.compute());
    }
}
  • UserTyper::new(CommandLineComputer):创建一个 UserTyper 实例,使用 CommandLineComputer 作为计算机。
  • typer.type_expr():提示用户输入一个表达式。
  • if typer.expr.contains("q"):如果用户输入了 “q”,则退出程序。
  • typer.compute():调用计算机进行计算,并打印结果。

计算机 Trait

trait Computer {
    fn compute(&self, expr: &str) -> i32;
}
  • 定义了一个 Computer trait,所有计算机都必须实现这个 trait。compute 方法接受一个字符串表达式,并返回一个整数结果。

命令行计算机实现

struct CommandLineComputer;

impl Computer for CommandLineComputer {
    fn compute(&self, expr: &str) -> i32 {
        // 初始化两个数字和一个操作符
        let mut num1 = String::new();
        let mut num2 = String::new();
        let mut op: Option<char> = None;

        // 遍历表达式中的每个字符
        for chr in expr.trim().chars() {
            if chr.is_digit(10) {
                // 如果是数字,根据操作符是否已确定,将数字添加到 num1 或 num2
                if op.is_none() {
                    num1.push(chr);
                } else {
                    num2.push(chr);
                }
                continue;
            }
            // 匹配操作符
            match chr {
                '+' | '-' | '*' | '/' if op.is_none() => op = Some(chr),
                _ if chr.is_whitespace() => continue,
                _ => panic!("Invalid character: {}", chr),
            }
        }

        // 检查表达式是否有效
        if num1.is_empty() || num2.is_empty() || op.is_none() {
            panic!("Invalid expression: {}", expr);
        }

        // 将字符串转换为数字
        let num1: i32 = num1.parse().unwrap();
        let num2: i32 = num2.parse().unwrap();
        let op: char = op.unwrap();

        // 根据操作符进行计算
        match op {
            '+' => num1 + num2,
            '-' => num1 - num2,
            '*' => num1 * num2,
            '/' => num1 / num2,
            _ => unreachable!(),
        }
    }
}
  • CommandLineComputer:一个简单的命令行计算机结构体。
  • compute 方法
    • 初始化两个数字字符串和一个操作符。
    • 遍历表达式中的每个字符,将数字和操作符分别存储。
    • 检查表达式是否有效。
    • 将字符串转换为数字。
    • 根据操作符进行计算并返回结果。

用户输入处理

struct UserTyper<T: Computer> {
    computer: T,
    expr: String,
}

impl<T: Computer> UserTyper<T> {
    fn new(computer: T) -> Self {
        Self {
            computer,
            expr: String::new(),
        }
    }

    fn type_expr(&mut self) {
        self.expr.clear();
        print!("Please type an expression: ");
        io::stdout().flush().unwrap();
        io::stdin()
            .read_line(&mut self.expr)
            .expect("Failed to read line");
    }

    fn compute(&self) -> i32 {
        self.computer.compute(&self.expr)
    }
}
  • UserTyper:一个结构体,用于处理用户输入和调用计算机进行计算。
  • new 方法:创建一个新的 UserTyper 实例。
  • type_expr 方法:提示用户输入一个表达式,并将其存储在 expr 中。
  • compute 方法:调用计算机进行计算,并返回结果。

运行程序

  1. 将代码保存为 main.rs
  2. 使用以下命令编译并运行程序:
    rustc main.rs
    ./main
    
  3. 在命令行中输入表达式,例如 10 + 20,程序将输出结果 30。输入 q 退出程序。

通过这个简单的项目,你可以看到 Rust 的强大功能,包括类型安全、模式匹配和错误处理。希望这个项目能帮助你更好地理解 Rust 编程!


网站公告

今日签到

点亮在社区的每一天
去签到