Borber 发表于 2021-12-16 16:47
Tags:错误传递, "?"
大佬们, 如何比较优雅的使用 ? 同时传递函数里的 result 和 option 的错误, 对于返回结构我一直把握不了. 用enum吗? 大佬们能否给个样例.
?
BTW 你这 get_current_dir 函数逻辑的等价写法是:
get_current_dir
use std::{env, io}; pub fn get_current_dir() -> Result<String, io::Error> { Ok(env::current_exe()? .parent() .map(|p| p.to_str()) .flatten() .unwrap_or("/") .to_string()) } fn main() { println!("当前运行目录: {:?}", get_current_dir()); }
-- 👇 Borber: 目前的新版本:
use std::{env, io}; pub fn get_current_dir() -> Result<String , &'static str> { let current_exe = match env::current_exe() { Ok(path) => {path} Err(e) => { return Err("Cannot find the current running directory"); } }; match current_exe.parent() { None => { Ok(String::from("/")) } Some(path) => { Ok(path.to_str().unwrap().to_string()) } } } #[test] fn test() -> Result<(), io::Error>{ println!( "当前运行目录: {:?}", get_current_dir().unwrap() ); Ok(()) }
感谢大佬, 太爱你了! 🤝
-- 👇 苦瓜小仔:
错误处理是 Rust 里面实践性很强的话题,你可以使用任何方式处理错误(包括 result 和 option,以及它们的混合体)。
既然你的意图是使用 ?,那么必须把返回值类型转成统一类型。最简的是 Result 转 Opton :
use std::env; pub fn get_current_dir() -> Option<String> { Some(env::current_exe().ok()?.parent()?.to_str()?.to_string()) } fn main() { println!("当前运行目录: {:?}", get_current_dir()); }
当然你可以统一成 Result 类型:
use std::{env, error}; pub fn get_current_dir() -> Result<String, Box<dyn error::Error>> { Ok(env::current_exe()? .parent() .ok_or("no parant")? .to_str() .ok_or("path is failed to convert to str")? .to_string()) } fn main() { println!("当前运行目录: {:?}", get_current_dir()); }
任何方式都有优点和不足。
Option 的方式丧失了中途所有错误信息,比如这里你得到一个 None,你不知道它在哪个环节有问题。
Result 的方式保留了所有错误信息,甚至你可以定义自己的类型来组织各种错误。
这完全取决于你的取舍和判断。
不过我认为你对 Option 或 Result 的一些 Combinators 似乎不够熟悉,你可以去了解一下,再思考怎么设计错误 API 的问题。
https://doc.rust-lang.org/rust-by-example/error/option_unwrap/map.html
https://learning-rust.github.io/docs/e6.combinators.html
https://www.yuque.com/zhoujiping/programming/rust-grammar-details#HQG8x
目前的新版本:
或者 例如我现在写的这样一个小功能:
use std::{env, io};
pub fn get_current_dir() -> String { env::current_exe().unwrap().parent().unwrap().to_str().unwrap().to_string() }
#[test] fn test() -> Result<(), io::Error>{ println!( "当前运行目录: {:?}", get_current_dir() ); Ok(()) }
我该怎么消除一些unwrap 让他更优雅一点以及不那么影响用户交互(直接退出
评论区
写评论BTW 你这
get_current_dir
函数逻辑的等价写法是:--
👇
Borber: 目前的新版本:
感谢大佬, 太爱你了! 🤝
--
👇
苦瓜小仔:
错误处理是 Rust 里面实践性很强的话题,你可以使用任何方式处理错误(包括 result 和 option,以及它们的混合体)。
既然你的意图是使用
?
,那么必须把返回值类型转成统一类型。最简的是 Result 转 Opton :当然你可以统一成 Result 类型:
任何方式都有优点和不足。
Option 的方式丧失了中途所有错误信息,比如这里你得到一个 None,你不知道它在哪个环节有问题。
Result 的方式保留了所有错误信息,甚至你可以定义自己的类型来组织各种错误。
这完全取决于你的取舍和判断。
不过我认为你对 Option 或 Result 的一些 Combinators 似乎不够熟悉,你可以去了解一下,再思考怎么设计错误 API 的问题。
https://doc.rust-lang.org/rust-by-example/error/option_unwrap/map.html
https://learning-rust.github.io/docs/e6.combinators.html
https://www.yuque.com/zhoujiping/programming/rust-grammar-details#HQG8x
错误处理是 Rust 里面实践性很强的话题,你可以使用任何方式处理错误(包括 result 和 option,以及它们的混合体)。
既然你的意图是使用
?
,那么必须把返回值类型转成统一类型。最简的是 Result 转 Opton :当然你可以统一成 Result 类型:
任何方式都有优点和不足。
Option 的方式丧失了中途所有错误信息,比如这里你得到一个 None,你不知道它在哪个环节有问题。
Result 的方式保留了所有错误信息,甚至你可以定义自己的类型来组织各种错误。
这完全取决于你的取舍和判断。
不过我认为你对 Option 或 Result 的一些 Combinators 似乎不够熟悉,你可以去了解一下,再思考怎么设计错误 API 的问题。
https://doc.rust-lang.org/rust-by-example/error/option_unwrap/map.html
https://learning-rust.github.io/docs/e6.combinators.html
https://www.yuque.com/zhoujiping/programming/rust-grammar-details#HQG8x
目前的新版本:
或者 例如我现在写的这样一个小功能:
use std::{env, io};
pub fn get_current_dir() -> String { env::current_exe().unwrap().parent().unwrap().to_str().unwrap().to_string() }
#[test] fn test() -> Result<(), io::Error>{ println!( "当前运行目录: {:?}", get_current_dir() ); Ok(()) }
我该怎么消除一些unwrap 让他更优雅一点以及不那么影响用户交互(直接退出