在Rust中有一个特殊的角色Result,是最常用的返回内容,如果是从其他语言转到Rust的话会觉得很别扭,很不习惯去处理Result(至少我是这样的),所以今天整理一下在Rust中如何处理Result,也是自我整理一下。
在说明之前需要先准备一段测试源代码:
rust
//执行返回Ok的result内容
fn rtn_ok() -> Result<i32, String> {
Ok(0)
}
//执行返回Err
fn rtn_err() -> Result<i32, String> {
Err("failed.".to_string())
}
使用match
使用match的方式针对Ok 、 Err 进行分支匹配,即通过对返回的Result进行判断,成功了该如何做,失败了该如何做,使用方式如下:
rust
let result = rtn_ok();
match result {
Ok(value) => println!("match Result is OK: {}", value),
Err(error) => println!("match Error: {}", &error),
}
let result = rtn_err();
match result {
Ok(value) => println!("match Result is OK: {}", value),
Err(error) => println!("match Error: {}", &error),
}
如果放在main函数中,执行返回结果如下:
bash
match Result is OK: 0
match Error: failed.
使用if let
是通过条件格式进行赋值判断分支
rust
// use if let
let result = rtn_ok();
if let Ok(value) = result { println!("if let Result is OK: {}", value);
} else if let Err(error) = result {
println!("if let Error: {}", error);
}
let result = rtn_err();
if let Ok(value) = result {
println!("if let Result is OK: {}", value);
} else if let Err(error) = result {
println!("if let Error: {}", &error);
}
执行结果如下:
bash
if let Result is OK: 0
if let Error: failed.
使用unwrap和expect
在使用unwrap 和 expect的时候,如果返回值是错误(Err),在运行期间会发生panic,所以直接在main函数中使用要小心。
rust
// use unwrap or expect
let value = rtn_ok().unwrap();
println!("unwrap Result is OK: {}", value);
let value = rtn_ok().expect("expect error");
println!("expect Result is OK: {}", value);
运行结果如下:
bash
unwrap Result is OK: 0
expect Result is OK: 0
如果运行期间返回Err,会提示panic
bash
thread 'main' panicked at src/main.rs:58:27:
called `Result::unwrap()` on an `Err` value: "failed."
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
使用'?'
这个'?'使用方式有点特别,如果在main() 函数中直接使用,并且函数返回值不为Result的话会提示异常
测试代码为:
rust
let value = rtn_ok()?;
运行的话会提示如下错误:
bash
67 | let value = rtn_ok()?;
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<Result<Infallible, String>>` is not implemented for `()`
这个错误起初我理解错了, 以为使用?的话返回值必须是(),而事实上并不是要求rtn_ok()这个函数返回值得问题, 而是使用?所在的函数体返回值必须是Result,假设我们添加如下测试源码:
rust
fn rtn_ok_kh(i: i32) -> Result<i32, String> {
if i == 0 {
Ok(0)
} else {
Err("rtn error kh".to_string())
}
}
fn rtn_info(i: i32) -> Result<i32, String> {
let value = rtn_ok_kh(i)?;
println!("? value is: {}", value);
Ok(value)
}
上面的代码中可以看到 rtn_info中对rtn_ok_kh()函数使用了"?",当rtn_ok_kh返回Ok时 可以正常赋值到value,返回Err时直接返回异常,main函数中测试代码如下:
rust
let result = rtn_info(0); if let Ok(value) = result {
println!("? Result is OK: {}", value);
} else if let Err(error) = result {
println!("? Error: {}", error);
}
let result = rtn_info(3);
if let Ok(value) = result {
println!("? Result is OK: {}", value);
} else if let Err(error) = result {
println!("? Error: {}", error);
}
执行后返回数据为:
bash
? value is: 0
? Result is OK: 0
? Error: rtn error kh
以上例子就能够看出"?"的使用方案了