繁体   English   中英

std :: fs ::文件+文档+试试! = E0308

[英]std::fs::File + documentation + try! = E0308

我想创建一个空文件,所以我一个例子 ,我使用今天的每晚构建

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! 是一个在返回Result函数中使用的宏。 因此,它不能在main函数中使用,因为它返回unit(空元组)。

看看它是如何扩展的:

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::unwrapFile::create("foo").unwrap() )可能是合理的。

我们来看看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作为一个表达式,要么从函数中返回一个Err 因此在处理宏之后,展开的代码如下所示:

fn main() {
    let mut f = (match File::create("foo") {
        Ok(val) => val,
        Err(err) => {
            return Err(...)
        }
    })
}

希望错误现在很明显: main()应该返回() ,但是返回一个Err (类型为Result<File> )。

这个故事的寓意是你在这里错误的场景中使用try!() 它应该仅用于已经设计为返回Result的函数内部,就像在C ++或Java中重新抛出(冒泡)异常一样。 但在你的情况下,你需要明确地处理错误 - 没有冒泡的可能性。 一个可能的解决方案,虽然不是很优雅,但是如果是Err ,则使用.unwrap().unwrap()程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM