【问题标题】:Cannot clone io::Error in 1.0.0 beta1.0.0 beta 中无法克隆 io::Error
【发布时间】:2015-05-03 02:40:38
【问题描述】:

我刚开始学习 Rust,但自从更新到 beta 版本后,我遇到了许多以前没有的编译错误。 其中之一与clone 有关,这是我的代码:

use std::io::{BufReader, BufRead};
use std::clone::Clone;
use std::env;
use std::fs::File;

pub fn main() {

    let ref path = match env::args().nth(1) {
            Some(path) => path,
            None => panic!("file path is missing!"), };

    let file = match File::open(&path) {
            Ok(file) => file,
            Err(_) => panic!("could not open {}", path), };

    let mut iter = BufReader::new(file).lines();
    let mut opt = iter.next();

    let str = opt.clone().unwrap().unwrap();

    // some code omitted
}

这是错误:

test.rs:19:19: 19:26 错误:类型 core::option::Option<core::result::Result<collections::string::String, std::io::error::Error>> 未在名为 clone 的范围内实现任何方法 test.rs:19 let str = opt.clone().unwrap().unwrap();

我需要clone,因为我在代码的其他部分使用了opt

是我的代码有问题,还是在 Rust 中发生了一些我不知道的更改?

【问题讨论】:

    标签: compiler-errors rust


    【解决方案1】:

    似乎错误信息让你感到困惑,所以让我们看一下:

    type `core::option::Option<core::result::Result<collections::string::String, std::io::error::Error>>` does not implement any method in scope named `clone`
    

    让我们稍微缩短一下类型:

    type `Option<Result<String, io::Error>>` does not implement any method in scope named `clone`
    

    那么,让我们看看Option。它说它实现了Clone

    impl<T> Clone for Option<T> where T: Clone + Clone
    

    我不确定Clone + Clone 发生了什么,但这表示“如果我的包含类型实现Clone,我可以实现Clone。所以让我们看看包含类型Result。它说明了什么类似的:

    impl<T, E> Clone for Result<T, E> where E: Clone + Clone, T: Clone + Clone
    

    好的,让我们检查一下String。它说它支持Cloneio::Error 怎么样?

    实现Clone,因此整个类型无法实现它。

    那么你如何解决它?在你的情况下,你不关心失败(你只是打开),所以先这样做:

    let str = opt.unwrap().unwrap().clone();
    

    这会克隆String 而不是所有中间状态。由于您克隆的数据更少,这甚至可能更有效。

    【讨论】:

    • 看起来 Clone + Clone 是一个 Rustdoc 错误,Copy 也会发生这种情况..
    【解决方案2】:

    看来std::io::Error 没有实现Clone,这就是问题所在。我看不出它不能的任何真正原因,所以我认为这只是一个疏忽。可能值得提交一个问题来支持它。

    与此同时,我能想到的最简单的解决方法是将Error 替换为您可以 克隆的东西。最快的方法是把它变成String

    let opt = opt.map(|r| r.map_err(|e| format!("{}", e)));
    

    如果您想保留实际的 Error 值,可以尝试将其移动到 Rc 中,以便共享所有权。

    【讨论】:

      【解决方案3】:

      为了使 .clone() 能够在 Result&lt;T, E&gt; 上工作,TE 都必须实现 Clone 特征。

      在这种情况下,您处理的是Result&lt;String, Error&gt;,但是Error 没有实现Clone

      【讨论】:

        猜你喜欢
        • 2016-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-17
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多