Rust- 错误处理

Rust approaches error handling with the aim of being explicit about possible error conditions. It separates the concerns of "normal" return values and "error" return values by using a specific set of types for each concern. Rust's primary tools for expressing these concepts are the Result and Option types, along with the unwrap method.

  1. The Result type : This is an enum that represents either successful (Ok) or unsuccessful (Err) computation. Functions that can fail generally return a Result variant.

    Here's a simple example:

    rust 复制代码
    fn divide(numerator: f64, denominator: f64) -> Result<f64, &str> {
        if denominator == 0.0 {
            Err("Cannot divide by zero")
        } else {
            Ok(numerator / denominator)
        }
    }

    In this case, if you try to divide by zero, the function will return an error wrapped in the Err variant. Otherwise, it will return the division result wrapped in the Ok variant.

  2. The Option type : This is another enum that represents a value that could be something (Some) or nothing (None). It's often used when you have a situation where a value could be absent or present.

    For example:

    rust 复制代码
    fn find_word_starting_with<'a, 'b>(sentence: &'a str, initial: &'b str) -> Option<&'a str> {
        for word in sentence.split_whitespace() {
            if word.starts_with(initial) {
                return Some(word);
            }
        }
        None
    }

    This function tries to find a word starting with a specific string in a sentence. If it finds such a word, it returns Some(word), otherwise, it returns None.

  3. The unwrap method : Both Option and Result types have an unwrap method, which is used to get the value out. If the instance of Option is a Some variant, unwrap will return the value inside the Some. If the instance is a None, unwrap will panic.

    Similarly, for Result, if the instance is an Ok, unwrap will return the value inside the Ok. If the instance is an Err, unwrap will panic.

    rust 复制代码
    let maybe_number: Option<i32> = Some(42);
    println!("{}", maybe_number.unwrap()); // Prints 42
    
    let definitely_not_a_number: Option<i32> = None;
    println!("{}", definitely_not_a_number.unwrap()); // This will panic

    It's generally advised to avoid using unwrap in most situations, as it can lead to your program crashing. Instead, you should handle errors appropriately using pattern matching or methods like unwrap_or, unwrap_or_else, expect, etc., which allow you to provide alternative values or actions in case of an error.

  4. The ? operator : This is a convenient way to propagate errors upwards in the call stack. When you use ? on a Result value, it does pretty much the same as a match expression would do: if the value is Ok, it unwraps it; if it's Err, it returns it from the current function. This allows for more concise error handling.

rust 复制代码
fn main() {
    match foo() {
        Ok(_) => println!("Success"),
        Err(e) => println!("Error: {}", e),
    }
}

fn foo() -> Result<(), &'static str> {
    bar()?;
    Ok(())
}

fn bar() -> Result<(), &'static str> {
    Err("Some error")
}

In the foo function, bar()? will return the error from bar, thus ending the foo function early.

These are the basic building blocks of error handling in Rust. Rust also provides advanced features like creating your own error types, using the From trait for flexible error conversions, etc., but those are more advanced topics.

rust 复制代码
use std::fs::File;

fn main() {
    panic!("出错了");
    println!("Hello Rust");

    // panic 程序立即退出,退出的时候调用者抛出退出原因。

    // 数组越界
    let v = vec!["Rust", "Programming", "Language"];
    println!("{}", v[5]); // thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 5'

    // 打开文件出错
    let f = File::open("abc.txt");
    println!("{:?}", f); // Err(Os { code: 2, kind: NotFound, message: "系统找不到指定的文件。" })

    // unwrap expect
    let result = is_even(6).unwrap();
    println!("结果{}", result);

    let result = is_even(11).unwrap();
    println!("结果{}", result);

    // unwrap()是Result<T, E>的方法,实例上调用此方法时,如果是Ok,就返回Ok中的对象
    // 如果是Err枚举,在运行时会panic

    // expect()接收msg::&str作为参数,可以自定义报错信息。
}

fn is_even(no: i32) -> Result<bool, String> {
    return if no % 2 == 0 {
        Ok(true)
    } else {
        Err("输入的值不是偶数".to_string())
    };
}
相关推荐
doiito6 小时前
【AI 应用】从“外国人味”到地道中文:kokoroi-rs v0.1.2 架构升级深度解析
ai·rust·系统设计
Zwarwolf10 小时前
Rust零散知识点项目汇总
开发语言·rust
X档案库12 小时前
【开源】我做了一套可以 AI 托管的 Markdown 博客与知识库
rust·博客·markdown·marksharex
程序员爱钓鱼17 小时前
Rust Vec 动态数组详解:创建、增删、遍历与排序
前端·后端·rust
_abab17 小时前
Rust重塑系统编程:从Linux内核到AI推理引擎的2026全景解析
linux·人工智能·rust
doiito1 天前
【Agent Harness】Gliding Horse 高级认知优化:让 Agent 的“大脑”和“免疫系统”真正协同
ai·rust·架构设计·系统设计·ai agent
longxiangam2 天前
第 4 篇:Embassy 异步运行时与事件驱动架构
单片机·嵌入式硬件·rust
程序员爱钓鱼2 天前
Rust String 与 &str 详解:字符串所有权、借用与转换
前端·后端·rust
段一凡-华北理工大学2 天前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
大卫小东(Sheldon)2 天前
小鹤音形词典:一个用 Rust 写的离线编码查询桌面工具
ai·rust