[英]Rust: move occurs because has type `ReadDir`, which does not implement the `Copy` trait
In https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html I find very similar example of using references for String
type, but in my code I got move occurs because `*paths_ref` has type `ReadDir`, which does not implement the `Copy` trait
.在https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html我发现非常相似的使用
String
类型引用的示例,但在我的代码中我得到了move occurs because `*paths_ref` has type `ReadDir`, which does not implement the `Copy` trait
。 What difference with String
?与
String
有什么区别? How I can use ReadDir
without memcopy there?我如何在没有 memcopy 的情况下使用
ReadDir
?
use std::fs;
const CACHE_ADDR: &str = ".";
fn get_files() -> std::fs::ReadDir {
fs::read_dir(CACHE_ADDR).unwrap()
}
fn main() {
let paths: std::fs::ReadDir = get_files();
let paths_ref = &paths;
println!("Count: {}", paths_ref.count());
for path in paths_ref.into_iter() {
println!("{:?}", path.unwrap().path());
break;
}
}
cargo build
error: cargo build
错误:
error[E0507]: cannot move out of `*paths_ref` which is behind a shared reference
--> src/main.rs:8:27
|
8 | println!("Count: {}", paths_ref.count());
| ^^^^^^^^^ move occurs because `*paths_ref` has type `ReadDir`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `*paths_ref` which is behind a shared reference
--> src/main.rs:9:17
|
9 | for path in paths_ref.into_iter() {
| ^^^^^^^^^ move occurs because `*paths_ref` has type `ReadDir`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0507`.
error: could not compile `osm-nca-proc`
To learn more, run the command again with --verbose.
The function fn calculate_length(s: &String) -> usize
takes a reference of String and returns an usize
, in this case, you own the returned value. function
fn calculate_length(s: &String) -> usize
接受 String 的引用并返回一个usize
,在这种情况下,您拥有返回的值。 When you do println.("The length of '{}' is {},", s1; len);
当你做
println.("The length of '{}' is {},", s1; len);
, your println macro trying to use s1
and len
. ,您的 println 宏尝试使用
s1
和len
。 There are no problem with this.这没有问题。
In your function, fn get_files() -> std::fs::ReadDir
return a ReadDir
struct, which you have the ownership of this struct, which is okay.在您的 function 中,
fn get_files() -> std::fs::ReadDir
返回一个ReadDir
结构,您拥有该结构的所有权,这没关系。
In the following line, you are creating a immutable reference to it let paths_ref = &paths;
在以下行中,您正在创建一个不可变的引用
let paths_ref = &paths;
, this is okay. ,这没关系。
In the line after that, you are trying to call paths_ref.count()
, this is not okay.在那之后的行中,您尝试调用
paths_ref.count()
,这是不行的。 Why?为什么?
count
is a method belong to trait Iterator
, if you look at the definition of count
method in Iterator, which is pub fn count(self) -> usize
, it takes the ownership of self
, and then return a usize
. count
是一个属于 trait Iterator
的方法,如果你看 Iterator 中count
方法的定义,即pub fn count(self) -> usize
,它获取了self
的所有权,然后返回一个usize
。 What this means is that as soon as you call count
, the Iterator is consumed and not exist anymore.这意味着只要您调用
count
,迭代器就会被消耗并且不再存在。
Because path_ref
is a reference of self
, and it doesn't own the ReadDir
data, you cannot call on count on it.因为
path_ref
是self
的引用,并且它不拥有ReadDir
数据,所以您不能对它调用 count 。 You can use paths.count()
which will consume the paths
variable and return a usize.您可以使用
paths.count()
,它将使用paths
变量并返回一个 usize。 But note after you call count
your paths
variable will not exist anymore and you can't use it in the below context.但是请注意,在您调用
count
之后,您的paths
变量将不再存在,并且您不能在以下上下文中使用它。
In your example, you essentially need to iterate the ReadDir
twice, one is to get the total count, and the other is to iterate the each element.在您的示例中,您基本上需要迭代
ReadDir
两次,一次是获取总计数,另一次是迭代每个元素。 You can achieve the same thing by using 1 iteration and manually count the total element (like using a counter i += 1
in each iteration), or you can call get_files
twice.您可以通过使用 1 次迭代并手动计算总元素来实现相同的目的(例如在每次迭代中使用计数器
i += 1
),或者您可以调用get_files
两次。
In the case you really want to iterate once, you can collect it (into a vec) and then you can use it to get the length and get iteration.如果你真的想迭代一次,你可以收集它(到一个 vec 中),然后你可以用它来获取长度并获取迭代。
I found a very similar stackoverflow question, you might want to check this one How to use the same iterator twice, once for counting and once for iteration?我发现了一个非常相似的 stackoverflow 问题,您可能想检查一下如何使用相同的迭代器两次,一次用于计数,一次用于迭代?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.