为什么在编译这段 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
这是来自 wifi-connect 项目。
Result
的定义始终如下:
pub enum Result<T, E> {
Ok(T),
Err(E),
}
这个定义甚至出现在Rust 编程语言中,以显示它是多么简单。作为 OK 结果和 error 结果的通用求和类型,它始终需要两个类型参数,如果编译器无法推断它们,或者类型参数列表没有预期的长度,则会抱怨。
另一方面,人们可能会发现许多库和各自的文档显示带有单个类型参数的
Result
,如 Result<()>
中所示。给什么?
这仍然没有魔法。按照惯例,库会在板条箱或模块级别为结果类型创建类型“别名”。这非常有效,因为这些错误通常会产生相同的本地创建类型的错误。
pub type Result<T> = std::result::Result<T, Error>;
或者,仍然可以声称是原始结果类型的定义。
pub type Result<T, E = Error> = std::result::Result<T, E>;
这种模式非常常见,以至于一些错误助手包(例如
)会自动为每个声明的错误创建一个结果别名类型。 因此,如果您使用的库可能使用或不使用
error-chain
,则您应该假设提及 Result<T>
是特定于域的 Result<T, Error>
的本地类型别名。如有疑问,在生成的文档页面中单击该类型将引导您找到具体定义(在本例中为别名)。部分 ?运算符只能用在返回结果的函数中
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let f = File::open("hello.txt")?;
Ok(())
}
use std::io::Result;
链接至类型描述
给出的投票最高的答案是正确的。但如果盲目应用则不起作用。在这两种情况下 这个
pub type Result<T> = Result<T, Error>;
还有这个
pub type Result<T, E = Error> = Result<T, E>;
会给出循环依赖错误
error[E0391]: cycle detected when expanding type alias `Result`
--> src\main.rs:149:33
|
149 | pub type Result<T, E = Error> = Result<T, E>;
| ^^^^^^^^^^^^
|
= note: ...which immediately requires expanding type alias `Result` again
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
因此,SO 的用户不想承认这一点,但是Gabriel soft
非常接近优雅的解决方案,因为该类型别名
pub type Result<T> = result::Result<T, Error>;
是直接来自
Result
在
std::io
(docs) 中定义。为了解决我添加的问题
use std::io::Result;
fn some_func() -> Result<()> {
...
}
或
use std::io;
fn some_func() -> io::Result<()> {
...
}
rustc1.62.1
Result
类型来处理错误来解决了我自己的错误。
它需要 T 和 E 的泛型,所以为了简化事情,我这样做了:pub type Result<T> = result::Result<T, Error>;