You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

简化Rust中的验证逻辑:优化双变量非空及无问号检查

优化你的Rust验证代码

原代码能实现需求,但有不少可以贴合Rust惯用写法的优化点,先上改进后的代码,再拆解优化细节:

#[derive(Debug)]
pub enum TestError {
    ContainsQuestionMark,
    NullInput,
}

pub type TestResult = Result<(), TestError>;

fn main() {
    let x = Some(String::from("x"));
    let y = Some(String::from("y"));

    match (x.as_ref(), y.as_ref()) {
        (Some(x_str), Some(y_str)) => {
            if let Err(TestError::ContainsQuestionMark) = validate(x_str, y_str) {
                println!("x or y contains ?");
                return;
            }
            out(x_str, y_str);
        }
        _ => {
            println!("x and y are Null");
            return;
        }
    }
}

fn validate(x: &str, y: &str) -> TestResult {
    if x.contains('?') || y.contains('?') {
        return Err(TestError::ContainsQuestionMark);
    }
    Ok(())
}

fn out(x: &str, y: &str) {
    println!("These are x = {x}, y = {y}");
}

核心优化点

  • 去掉冗余的克隆与unwrap:原代码先判断is_some()再clone().unwrap()完全没必要,用as_ref()将Option<String>转为Option<&String>,再通过模式匹配直接拿到引用,避免了无意义的内存拷贝。
  • 优化错误类型与返回值:
    1. 给TestError新增NullInput枚举值,让错误类型更清晰,后续扩展也更方便;
    2. validate函数返回Result<(), TestError>而非Result<bool, TestError>——验证成功不需要传递额外值,Ok(())足够表达成功状态,更符合Rust错误处理的设计思路。
  • 参数类型更通用:把validate和out的参数从&String改成&str,&String会自动 Deref 为&str,这样函数不仅能接收字符串引用,还能兼容字符串字面量等其他实现Deref<Target=str>的类型。
  • 移除不必要的进程退出:原out函数里的std::process::exit(0)完全多余,main函数正常执行完毕就会返回0退出,手动调用反而画蛇添足。
  • 用模式匹配替代嵌套if:通过match (x.as_ref(), y.as_ref())直接匹配两个Option的状态,代码结构更扁平,可读性更强。
  • 字符匹配更高效:把contains("?")改成contains('?'),前者匹配字符串,后者匹配单个字符,性能更优。

更简洁的错误处理写法

如果想进一步简化代码,可以让main函数返回Result,用?操作符自动处理错误:

#[derive(Debug)]
pub enum TestError {
    ContainsQuestionMark,
    NullInput,
}

pub type TestResult = Result<(), TestError>;

fn main() {
    if let Err(e) = inner_main() {
        match e {
            TestError::NullInput => println!("x and y are Null"),
            TestError::ContainsQuestionMark => println!("x or y contains ?"),
        }
    }
}

fn inner_main() -> TestResult {
    let x = Some(String::from("x"));
    let y = Some(String::from("y"));

    // 把Option转为Result,用?自动处理空值错误
    let (x_str, y_str) = x.as_ref()
        .and_then(|x_val| y.as_ref().map(|y_val| (x_val, y_val)))
        .ok_or(TestError::NullInput)?;

    validate(x_str, y_str)?;
    out(x_str, y_str);

    Ok(())
}

fn validate(x: &str, y: &str) -> TestResult {
    if x.contains('?') || y.contains('?') {
        Err(TestError::ContainsQuestionMark)
    } else {
        Ok(())
    }
}

fn out(x: &str, y: &str) {
    println!("These are x = {x}, y = {y}");
}

这种写法把业务逻辑和错误展示分离,代码更简洁,完全去掉了嵌套判断,是Rust中处理这类场景的惯用方式。

内容的提问来源于stack exchange,提问作者MarieGosnell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:25:07