std::fs::File + 文档 + 试用! = E0308
std::fs::File + documentation + try! = E0308
我想创建一个空文件,所以我选择了 an example 并使用了今天的夜间构建
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut f = try!(File::create("foo"));
}
运行 rustc
有错误:
<std macros>:5:8: 6:42 error: mismatched types:
expected `()`,
found `core::result::Result<_, _>`
(expected (),
found enum `core::result::Result`) [E0308]
<std macros>:5 return $ crate:: result:: Result:: Err (
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
<std macros>:1:1: 6:48 note: in expansion of try!
file_io.rs:5:17: 5:42 note: expansion site
<std macros>:5:8: 6:42 help: pass `--explain E0308` to see a detailed explanation
error: aborting due to previous error
如果我删除 try!
,它会编译,但我应该如何处理错误?为什么示例没有按原样编译?
我们来看看try!()
宏:
macro_rules! try {
($expr:expr) => (match $expr {
$crate::result::Result::Ok(val) => val,
$crate::result::Result::Err(err) => {
return $crate::result::Result::Err($crate::convert::From::from(err))
}
})
}
如您所见,try!()
生成 val
作为表达式,或者 return 是函数外的 Err
。所以在宏被处理之后,展开的代码看起来像:
fn main() {
let mut f = (match File::create("foo") {
Ok(val) => val,
Err(err) => {
return Err(...)
}
})
}
希望错误现在很明显:main()
应该 return ()
,但是你 return 一个 Err
(类型 Result<File>
).
故事的寓意是您在错误的场景中使用了 try!()
。它只能在已经设计为 return 和 Result
的函数中使用,就像您在 C++ 或 Java 中重新抛出(冒泡)异常一样。但是,在您的情况下,您需要明确处理错误——不可能冒泡。一个可能的解决方案,虽然不是很优雅,但在 Err
.
的情况下使用 .unwrap()
使程序崩溃
try!
是一个宏,用于 return 和 Result
的函数中。因此,它不能用在 main
函数中,因为它是 return 单元(空元组)。
看看它是如何展开的:
fn main() {
let mut f = match File::create("foo") {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
}
http://blog.burntsushi.net/rust-error-handling/ 是一篇关于 Rust 错误处理的好文章;对于像您这样的简单脚本,使用 Result::unwrap
(File::create("foo").unwrap()
) 可能是合理的。
我想创建一个空文件,所以我选择了 an example 并使用了今天的夜间构建
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut f = try!(File::create("foo"));
}
运行 rustc
有错误:
<std macros>:5:8: 6:42 error: mismatched types:
expected `()`,
found `core::result::Result<_, _>`
(expected (),
found enum `core::result::Result`) [E0308]
<std macros>:5 return $ crate:: result:: Result:: Err (
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
<std macros>:1:1: 6:48 note: in expansion of try!
file_io.rs:5:17: 5:42 note: expansion site
<std macros>:5:8: 6:42 help: pass `--explain E0308` to see a detailed explanation
error: aborting due to previous error
如果我删除 try!
,它会编译,但我应该如何处理错误?为什么示例没有按原样编译?
我们来看看try!()
宏:
macro_rules! try {
($expr:expr) => (match $expr {
$crate::result::Result::Ok(val) => val,
$crate::result::Result::Err(err) => {
return $crate::result::Result::Err($crate::convert::From::from(err))
}
})
}
如您所见,try!()
生成 val
作为表达式,或者 return 是函数外的 Err
。所以在宏被处理之后,展开的代码看起来像:
fn main() {
let mut f = (match File::create("foo") {
Ok(val) => val,
Err(err) => {
return Err(...)
}
})
}
希望错误现在很明显:main()
应该 return ()
,但是你 return 一个 Err
(类型 Result<File>
).
故事的寓意是您在错误的场景中使用了 try!()
。它只能在已经设计为 return 和 Result
的函数中使用,就像您在 C++ 或 Java 中重新抛出(冒泡)异常一样。但是,在您的情况下,您需要明确处理错误——不可能冒泡。一个可能的解决方案,虽然不是很优雅,但在 Err
.
.unwrap()
使程序崩溃
try!
是一个宏,用于 return 和 Result
的函数中。因此,它不能用在 main
函数中,因为它是 return 单元(空元组)。
看看它是如何展开的:
fn main() {
let mut f = match File::create("foo") {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
}
http://blog.burntsushi.net/rust-error-handling/ 是一篇关于 Rust 错误处理的好文章;对于像您这样的简单脚本,使用 Result::unwrap
(File::create("foo").unwrap()
) 可能是合理的。