简体   繁体   English

Rust:发生移动是因为类型为 `ReadDir`,它没有实现 `Copy` 特征

[英]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 宏尝试使用s1len 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_refself的引用,并且它不拥有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.

相关问题 发生 Rust 文件树移动是因为 `subtree` 的类型为 `trees::Tree<PathBuf> `,它没有实现 `Copy` 特征 - Rust File Tree move occurs because `subtree` has type `trees::Tree<PathBuf>`, which does not implement the `Copy` trait 由于 `slice[_]` 的类型为 `T`,它没有实现 `Copy` 特征,因此无法移出此处发生移动 - Cannot move out of here move occurs because `slice[_]` has type `T`, which does not implement the `Copy` trait 移动发生是因为值的类型为 Vec<T> ,它没有实现 `Copy` 特性 - move occurs because value has type Vec<T>, which does not implement the `Copy` trait move 发生是因为 value 的类型为 `RefCell&lt;…&gt;`,它没有实现 `Copy` 特征 - move occurs because value has type `RefCell<…>`, which does not implement the `Copy` trait 如何避免“由于`v`的类型为`Vec而发生移动<char> `,它没有在循环中实现`Copy` trait&quot; - How to avoid "move occurs because `v` has type `Vec<char>`, which does not implement the `Copy` trait" within loop 在匹配中分配向量的值:移动发生......它没有实现“复制”特征 - Assigning value of vector inside match: move occurs … which does not implement the `Copy` trait &#39;移动发生是因为值具有类型&#39; Rust 错误 - 'move occurs because value has type' Rust error Rust 编译错误:'发生移动是因为 `self.styles` 的类型为 `HashMap&lt;&amp;str, &amp;str&gt;`' - Rust compilation error: 'move occurs because `self.styles` has type `HashMap<&str, &str>`' 无法移出位于共享引用移动后面的 `*handle`,因为 `*handle` 具有类型 - cannot move out of `*handle` which is behind a shared reference move occurs because `*handle` has type `bigdecimal::BigDecimal`,它没有实现 `Copy` 特性 - `bigdecimal::BigDecimal`, which does not implement the `Copy` trait
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM