数码帮手
白蓝主题五 · 清爽阅读
首页  > 视频工具

Rust编程Result类型:写视频工具时如何优雅处理错误

ref="/tag/116/" style="color:#874873;font-weight:bold;">视频工具开发时,文件读取失败、编码器崩溃、路径不存在这些问题天天见。以前用 Python 或 C++ 时,不是抛异常就是返回 -1,调用方一不小心就让程序直接崩了。自从在项目里用了 Rust 的 Result 型,这类问题明显少了很多。

Result 到底是什么?

Rust 没有异常机制,取而代之的是 Result<T, E>。它是一个枚举,只有两个分支:Ok(T) 表示成功,Err(E) 表示出错。函数执行完,不会偷偷摸摸改全局状态,而是明明白白告诉你:“我成了”或者“我翻车了”。

fn read_video_file(path: &str) -> Result<Vec<u8>, String> {
if path.ends_with(".mp4") {
Ok(vec![0, 1, 2, 3]) // 模拟读取成功
} else {
Err(String::from("不支持的格式"))
}
}

这个 read_video_file 函数,输入路径,返回一个 Result。如果后缀是 .mp4,就假装读到了数据;否则返回错误信息。调用的时候必须处理两种情况,编译器不让你偷懒。

用 match 处理结果

最直接的方式是 match:

match read_video_file("test.avi") {
Ok(data) => println!("读取了 {} 字节", data.len()),
Err(e) => println!("出错了:{}", e),
}

这样逻辑清晰,但写多了有点啰嗦。好在 Rust 提供了很多便捷方法。

unwrap 和 expect:调试时的好帮手

开发阶段想快速验证流程,可以直接用 unwrap:

let data = read_video_file("video.mp4").unwrap();

如果返回的是 Err,程序会 panic,打印堆栈。expect 更贴心一点,能自定义提示:

let data = read_video_file("video.mkv").expect("读取视频失败,请检查格式");

适合测试用,别往生产环境扔。

?

真正写业务逻辑时,? 运算符才是救星。它能把 Result 里的错误自动向上抛,省得一层层手动 match。

fn process_video(path: &str) -> Result<(), String> {
let data = read_video_file(path)?;
println!("开始处理视频数据,共 {} 字节", data.len());
Ok(())
}

如果 read_video_file 返回 Err,process_video 也会立刻返回那个错误。代码一下子清爽了。

实际场景:批量转码视频

假设你要写个工具,遍历目录下所有视频,批量转成 H.265。每个文件都可能出问题:打不开、编码器报错、磁盘满……用 Result 能让你清楚知道哪一步卡住了。

fn transcode_one(file: &str) -> Result<(), String> {
let input = read_video_file(file)?;
// 模拟编码过程
if input.is_empty() {
return Err(String::from("空文件无法编码"));
}
println!("✅ {} 转码完成", file);
Ok(())
}

主流程可以遍历文件列表,逐个尝试转码,记录失败项,而不是整个任务因为一个文件就停摆。

和 Option 一样,Result 是日常操作

在写视频工具时,打开摄像头、解析元数据、写入输出文件,每个环节都可能出错。Rust 把这些可能性摊开在类型系统里,逼你面对现实。时间久了你会发现,程序稳定性高了,同事接手也更容易——谁调用谁负责,清清楚楚。

不用再靠文档里那句“本函数可能返回 null”来提醒别人小心。Result 写在签名里,逃不掉的。