无法在 1.0.0 beta 中克隆 io::Error
Cannot clone io::Error in 1.0.0 beta
我刚开始学习Rust,但是自从更新到测试版后,我遇到了很多以前没有的编译错误。
其中之一与 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 error: type core::option::Option<core::result::Result<collections::string::String, std::io::error::Error>>
does not implement any method in scope named clone
test.rs:19 let str = opt.clone().unwrap().unwrap();
我需要 clone
因为我在代码的其他部分使用了 opt
。
是我的代码有问题,还是有一些我不知道的东西在 Rust 中发生了变化?
std::io::Error
似乎没有实现 Clone
,这就是问题所在。我没有看到它 不能 的任何真正原因,所以我认为这只是一个疏忽。可能值得提出一个问题来支持它。
与此同时,我能想到的最简单的解决方法是将 Error
替换为您 可以 克隆的东西。最快的方法是将其变成 String
:
let opt = opt.map(|r| r.map_err(|e| format!("{}", e)));
如果您想保留实际的 Error
值,您可以尝试将其移动到 Rc
中,以便您共享所有权。
看来错误信息让你感到困惑,所以让我们看一下:
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
. It says it supports Clone
. How about io::Error
?
这不实现Clone
,因此整个类型无法实现它。
那你是怎么解决的呢?在你的情况下,你不关心失败(你只是打开),所以先这样做:
let str = opt.unwrap().unwrap().clone();
这会克隆 String
而不是所有中间状态。这甚至可能会稍微高效一些,因为您克隆的数据较少。
为了 .clone()
在 Result<T, E>
上工作,T
和 E
都必须实现 Clone
特性。
在这种情况下,您处理 Result<String, Error>
,但是 Error
没有实现 Clone
!
我刚开始学习Rust,但是自从更新到测试版后,我遇到了很多以前没有的编译错误。
其中之一与 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 error: type
core::option::Option<core::result::Result<collections::string::String, std::io::error::Error>>
does not implement any method in scope namedclone
test.rs:19 let str = opt.clone().unwrap().unwrap();
我需要 clone
因为我在代码的其他部分使用了 opt
。
是我的代码有问题,还是有一些我不知道的东西在 Rust 中发生了变化?
std::io::Error
似乎没有实现 Clone
,这就是问题所在。我没有看到它 不能 的任何真正原因,所以我认为这只是一个疏忽。可能值得提出一个问题来支持它。
与此同时,我能想到的最简单的解决方法是将 Error
替换为您 可以 克隆的东西。最快的方法是将其变成 String
:
let opt = opt.map(|r| r.map_err(|e| format!("{}", e)));
如果您想保留实际的 Error
值,您可以尝试将其移动到 Rc
中,以便您共享所有权。
看来错误信息让你感到困惑,所以让我们看一下:
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
. It says it supports Clone
. How about io::Error
?
这不实现Clone
,因此整个类型无法实现它。
那你是怎么解决的呢?在你的情况下,你不关心失败(你只是打开),所以先这样做:
let str = opt.unwrap().unwrap().clone();
这会克隆 String
而不是所有中间状态。这甚至可能会稍微高效一些,因为您克隆的数据较少。
为了 .clone()
在 Result<T, E>
上工作,T
和 E
都必须实现 Clone
特性。
在这种情况下,您处理 Result<String, Error>
,但是 Error
没有实现 Clone
!