【问题标题】:Rust: move occurs because has type `ReadDir`, which does not implement the `Copy` traitRust:发生移动是因为具有类型 `ReadDir`,它没有实现 `Copy` 特征
【发布时间】:2021-05-03 22:33:39
【问题描述】:

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。与String 有什么区别?我如何在没有 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[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.

【问题讨论】:

  • 问题是countinto_iter 使用迭代器,而String::len 使用引用。

标签: rust


【解决方案1】:

函数fn calculate_length(s: &String) -> usize 接受String 的引用并返回usize,在这种情况下,您拥有返回值。当您执行println!("The length of '{}' is {}.", s1, len); 时,您的println 宏会尝试使用s1len。这没有问题。

在你的函数中,fn get_files() -> std::fs::ReadDir 返回一个ReadDir 结构,你拥有这个结构的所有权,这没关系。

在以下行中,您正在创建一个对它的不可变引用let paths_ref = &paths;,这没关系。

在那之后的那一行,你试图打电话给paths_ref.count(),这是不行的。为什么? count是一个属于traitIterator的方法,如果你看Iterator中count方法的定义,也就是pub fn count(self) -> usize,它获取self的所有权,然后返回一个usize。这意味着只要你调用count,迭代器就会被消耗掉并且不再存在。

因为path_refself 的引用,并且它不拥有ReadDir 数据,所以您不能对它调用count。您可以使用paths.count(),它将使用paths 变量并返回一个usize。但是请注意,在您调用 count 之后,您的 paths 变量将不再存在,并且您不能在以下上下文中使用它。

在您的示例中,您基本上需要迭代ReadDir 两次,一次是获取总数,另一次是迭代每个元素。您可以通过使用 1 次迭代并手动计算总元素来实现相同的目的(例如在每次迭代中使用计数器 i += 1),或者您可以调用 get_files 两次。

如果你真的想迭代一次,你可以收集它(到一个 vec 中),然后你可以用它来获取长度并获取迭代。

我发现了一个非常相似的 stackoverflow 问题,您可能想查看这个问题 How to use the same iterator twice, once for counting and once for iteration?

【讨论】:

    猜你喜欢
    • 2022-06-16
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2015-09-19
    • 2016-05-29
    • 1970-01-01
    相关资源
    最近更新 更多