为什么编译这部分Rust代码时不允许Result<()>
? Rust版本之间是否有重大变化?
fn run() -> Result<()> {
let (tx, rx) = channel();
thread::spawn(move || {
do_things_with_tx(&exit_tx);
});
match exit_rx.recv() {
Ok(result) => if let Err(reason) = result {
return Err(reason);
},
Err(e) => {
return Err(e.into());
},
}
Ok(())
}
编译器说:
error[E0107]: wrong number of type arguments: expected 2, found 1
--> src/main.rs:1000:18
|
1000 | fn run_wifi() -> Result<()> {
| ^^^^^^^^^^ expected 2 type arguments
当我将返回类型调整为Result<(), Err>
时,它说:
error[E0107]: wrong number of type arguments: expected 2, found 0
--> src/main.rs:1000:29
|
1000 | fn run() -> Result<(), Err> {
| ^^^ expected 2 type arguments
这来自Semaphore。早晨将跟踪可重复的MVCE。
答案 0 :(得分:8)
Result
的定义始终是以下内容:
pub enum Result<T, E> {
Ok(T),
Err(E),
}
这个定义甚至在the Rust Programming language中也有介绍,以表明它的简单性。作为 OK 结果和 error 结果的通用和类型,它总是期望两个类型参数,并且编译器会抱怨它无法推断它们或类型参数列表没有预期的长度。
另一方面,可能会发现许多库和相应的文档显示了带有单个类型实参的Result
,如Result<()>
中所示。有什么作用?
这仍然不是魔术。按照惯例,库在板条箱或模块级别为结果类型创建类型别名。这样效果很好,因为通常会产生相同的本地创建类型的错误。
pub type Result<T> = Result<T, Error>;
事实上,很普遍,当使用error_chain!
宏时,许多错误类型辅助工具之一的工具箱error-chain
会自动创建此定义。
因此,如果您在使用error-chain
(such as wifi-connect
)的项目中,或者正在使用可能会或可能不会使用error-chain
的库中,则应该假定提到了{{1 }}是特定于域的Result<T>
的本地类型别名。如有疑问,请在生成的文档页面中单击该类型,将您带到具体定义(在本例中为别名)。
答案 1 :(得分:1)
来自The Rust Programming Language部分The ? Operator Can Only Be Used in Functions That Return Result
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let f = File::open("hello.txt")?;
Ok(())
}