Rust如何从函数返回当前工作目录 及Result与Ok(())用法疑问
问题解答
报错原因
Rust标准库的Result是需要两个泛型参数的枚举类型,定义结构为:
enum Result<T, E> { Ok(T), // 操作成功时的变体,存储成功返回值 Err(E), // 操作失败时的变体,存储错误信息 }
你原代码中get_current_working_dir的返回值写为Result<T>,只提供了1个泛型参数,不符合语法要求,所以触发E0107报错。
另外std::env::current_dir()本身的返回类型是std::io::Result<PathBuf>,也就是Result<PathBuf, std::io::Error>,你不需要额外定义泛型T,直接补全正确的返回类型即可。
Ok(()) 是什么
Ok是Result枚举的成功分支变体,后面括号里的内容是成功返回的具体值:
- 当操作成功不需要返回任何有效数据时,就会返回
Ok(()),这里的()是Rust的单元类型,类似于其他语言的void返回值 - 你期望输出里的
Ok("/home/tomand/rcp"),就是成功返回了工作目录的路径值,被包裹在Ok变体里
达到你期望输出的实现方案
不需要直接把Result转成String,只要修正函数签名,直接打印Result变量即可:
// 补全正确的返回类型 fn get_current_working_dir() -> std::io::Result<std::path::PathBuf> { env::current_dir() } fn main() { let WORKING_DIR = get_current_working_dir(); // 用{:#?}格式化打印,就会输出你期望的缩进格式的Ok结构 println!("{:#?}", WORKING_DIR); // 剩下的原有逻辑 let args: Vec<String> = collect_user_arguments(); if check_if_arguments_count_valid(&args) { let arg1 = &args[1]; let arg2 = &args[2]; println!("{:#?}", determinate_is_it_file_or_dirctory(&arg1)); } }
运行后就会输出你想要的:
Ok( "/home/tomand/rcp", )
你最终采用的实现方案是直接把Result的两种分支都转换成了String返回,适合不需要保留错误详情的简单工具场景,逻辑没有问题;如果后续需要针对不同错误做差异化处理,保留Result类型会更灵活。
Result常用处理方式
- 确定操作不会出错的场景:用
unwrap()/expect("自定义错误提示")直接取出Ok里的值,出错时会直接panic终止程序 - 需要传播错误的场景:在返回Result的函数里用
?运算符,遇到Err会直接把错误返回给上层调用者 - 需要分别处理成功失败的场景:用
match或者if let分支分别处理Ok和Err的情况
内容的提问来源于stack exchange,提问作者pr0logas
相关产品推荐
相关产品推荐

