rust - Rust:移动发生是因为具有类型 `ReadDir`,它没有实现 `Copy` 特征
问题描述
在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
?我如何在ReadDir
没有 memcopy 的情况下使用?
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.
解决方案
该函数fn calculate_length(s: &String) -> usize
接受 String 的引用并返回一个usize
,在这种情况下,您拥有返回的值。当您这样做时println!("The length of '{}' is {}.", s1, len);
,您的 println 宏会尝试使用s1
和len
. 这没有问题。
在您的函数中,fn get_files() -> std::fs::ReadDir
返回一个ReadDir
结构,您拥有该结构的所有权,这没关系。
在以下行中,您正在创建对它的不可变引用let paths_ref = &paths;
,这没关系。
在那之后的那一行,你试图打电话paths_ref.count()
,这是不行的。为什么?count
是一个属于 trait 的方法Iterator
,如果你看count
Iterator 中方法的定义,也就是pub fn count(self) -> usize
它取得 的所有权self
,然后返回一个usize
。这意味着只要您调用count
, Iterator 就会被消耗并且不再存在。
因为path_ref
是 的引用self
,并且它不拥有ReadDir
数据,所以您不能调用 count 。您可以使用paths.count()
which 将使用该paths
变量并返回一个使用大小。但是请注意,在您调用变量后,count
您的paths
变量将不再存在,并且您不能在以下上下文中使用它。
在您的示例中,您基本上需要迭代ReadDir
两次,一次是获取总计数,另一次是迭代每个元素。您可以通过使用 1 次迭代并手动计算总元素(例如i += 1
在每次迭代中使用计数器)来实现相同的目的,或者您可以调用get_files
两次。
如果你真的想迭代一次,你可以收集它(到一个 vec 中),然后你可以用它来获取长度并获取迭代。
我发现了一个非常相似的 stackoverflow 问题,您可能想检查一下 如何使用相同的迭代器两次,一次用于计数,一次用于迭代?
推荐阅读
- ruby - 红宝石语法错误'require_relative'
- php - 简单的逻辑计算在 PHP 中不起作用
- python - 如何在Python中将变量与值匹配
- node.js - 如何在类型脚本中创建泛型类型参数的实例
- python - 通过隐式方程修改像素
- visual-studio - 公式车间水晶报表 2008 中出现“此处应有声明”错误
- iis-8 - 我的 C#asp.net 项目可以在 Windows7 IIS 中加载 pdf 报告,但在 Windows10 和 windows Server 2012 r2 IIS 中无法加载 pdf 报告
- jacoco - 使用 Jacoco 的代码覆盖率在不同的存储库中具有应用程序代码库和测试代码库
- .net - 环境变量作为 azure web 应用程序中 web.config 中重写规则的条件
- jenkins - 詹金斯管道战略 - 公关工作和开发工作