发布于2026-07-24 阅读(0)
扫一扫,手机访问
在Rust的世界里,错误处理有一套非常优雅的玩法——核心就是Result类型和?操作符。这两个东西组合起来,能让你写出既安全又简洁的代码。

先说说Result。它本质上是一个枚举,只有两个变体:Ok(T)表示操作成功,并带着返回的值;Err(E)表示操作失败,附带错误信息。当你需要处理可能失败的操作时——比如打开文件、读取网络请求——就应该用Result来包装返回值。
举个例子,假设你想打开一个文件:
use std::fs::File;
use std::io::Error;
fn open_file(path: &str) -> Result {
File::open(path)
}
这里open_file函数返回一个Result:成功时是Ok(File),失败时是Err(Error)。调用方拿到这个结果后,必须处理它——要么展开,要么传递。
那么问题来了:如果每个可能失败的地方都写一堆match,代码会变得非常啰嗦。这时候?操作符就派上用场了。它的作用很直接:如果Result是Ok,就取出内部的值继续执行;如果是Err,就立刻把错误返回给上层调用者,提前退出函数。
看个实际例子:读取文件内容。
use std::fs::{self, File};
use std::io::{self, Read};
fn read_file_contents(path: &str) -> Result {
let mut file = open_file(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
注意这里两个?:第一个尝试打开文件,如果失败就直接返回错误;第二个尝试读取内容,同样如果失败就提前返回。整个函数看起来干净利落,错误传播的路径一目了然。
最后,错误总归要处理。Rust 提供了多种方式:你可以用match手动匹配Result的两个分支,也可以用unwrap或expect快速获取值——但后者在生产环境里要格外谨慎,因为它们一旦遇到错误就会让程序直接崩溃。更好的做法是优雅地处理,比如:
fn main() {
match read_file_contents("example.txt") {
Ok(contents) => println!("File contents: {}", contents),
Err(error) => eprintln!("Error reading file: {}", error),
}
}
成功时打印内容,失败时把错误信息输出到标准错误流。这样代码既健壮,又不会因为一个小错误就整个崩掉。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8