rust - 在 Rust 中重用变量

标签 rust move-semantics

我有以下代码:

let display_value = entry.path().display();
files_and_dirs.push(DiskEntry {
    path: display_value.to_string(),
    is_dir: is_dir(display_value.to_string()),
    name: display_value.to_string()
});

如果我这样写:

let display_value = entry.path().display();
let dir_name = display_value.to_string();
files_and_dirs.push(DiskEntry {
    path: dir_name,
    is_dir: is_dir(dir_name),
    name: dir_name
});

我收到以下错误:

move occurs because dir_name has type std::string::String, which does not implement the Copy trait

我知道在 Rust 中,值在分配时会四处 move 。我想声明一个变量并在第二个代码块中多次使用它。我该怎么做?

最佳答案

您的 DiskEntryis_dir 大概是这样定义的:

struct DiskEntry {
    path: String,
    is_dir: bool,
    name: String,
}

fn is_dir(path: String) -> bool {
    // ...
}

每次有一个类型为String的变量时,该变量都需要在内存中有自己的字符串副本。

如错误所示,您可以通过克隆来修复它:

let display_value = entry.path().display();
let dir_name = display_value.to_string();
files_and_dirs.push(DiskEntry {
    path: dir_name.clone(),
    is_dir: is_dir(dir_name.clone()),
    name: dir_name
});

但是您应该避免不必要地克隆数据,因为它效率低下。非常容易删除的克隆位于 is_dir - 很明显,此方法不需要永久获取其输入的所有权。它可以很容易地借用它:

fn is_dir(path: &str) -> bool {
    // ...
}

你会这样调用它,所以 String 被借用为 &str:

is_dir(&dir_name),

另一种情况可能更棘手。为了避免克隆,您需要使 DiskEntry 结构借用字符串。它看起来像这样:

struct DiskEntry<'a> {
    path: &'a str,
    is_dir: bool,
    name: &'a str,
}

let display_value = entry.path().display();
let dir_name = display_value.to_string();
files_and_dirs.push(DiskEntry {
    path: &dir_name,
    is_dir: is_dir(&dir_name),
    name: &dir_name
});

但是,这将限制您可以使用 DiskEntry 执行的操作;特别是,它不能超过 dir_name 变量。在不了解代码的更广泛上下文的情况下,很难知道这可能会给您带来什么其他问题,但它可能会对其他数据结构产生更广泛的影响。

鉴于您似乎只是在学习 Rust,如果您对借用和生命周期还不满意,那么最简单的方法可能就是接受这个额外的克隆,直到您有更好的理解并可以自己做出判断。


另见:

关于rust - 在 Rust 中重用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56312330/

相关文章:

asynchronous - 如何加入向量中的所有 future 而不会像 join_all 那样取消失败?

c++ - 返回 std::stringstream - 编译失败

c++ - 在 C++11 中抛出异常时是否使用 move 语义?

c++ - 是否需要销毁移出的对象?

unit-testing - 在 Rust 中进行单元测试后清理的好方法是什么?

module - Rust 无法将 Singleton 从全局空间导入另一个文件中的另一个模块

generics - 可克隆类型和可复制类型的特征

c++ - 使用 C++11 复制和 move 时避免代码重复

c++ - 当从函数返回元组时,元组的参数被复制而不是 move

rust - 有没有更好的方法来获取对不相交结构字段的可变引用?