理解 Rust 中涉及结构的移动语义的微妙之处

问题描述 投票:0回答:1

我构建了这个代码示例,其中(是|不是)被认为是一个移动,因此(是|不是)被允许在 Rust 中编译,效果看起来不一致

struct Foo {
    bar: String,
    bazs: Vec<String>,
}


fn main() {
    let a: Foo = Foo {
        bar: "bar".to_string(),
        bazs: vec!["baz_1".to_string(), "bax_2".to_string()],
    };
    
    let b: String = a.bar;
    
    println!{"Who owns the String value, variable a or b? {b}"};
    
    
    // assigning a String (from a field of String type) to b IS NOT considered a move
    // assigning a String (from an element of field of Vec<String> type to IS considered a move
    // let c: String = a.bazs[0];
}

Rust 游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=da8bd7ae7b19ee2d388dbd9fe370f93d

该示例基于对《Rust 编程语言》一书的阅读,与讨论字符串移动的 ss 部分相关,但尚未提供足够的推理来让我理解这个构造的示例:

我希望得到一些关于如何正确理解这个问题的指导

rust move
1个回答
0
投票

Rust 有部分动作。您可以将

a.bar
a.bazs
分别移出
a
。您不能做的是在移出任何(非
a
)字段后完整使用
Copy
。但个别未移动的字段仍然是公平的游戏。所以这很好:

let a: Foo = Foo {
    bar: "bar".to_string(),
    bazs: vec!["baz_1".to_string(), "bax_2".to_string()],
};

let b = a.bar;
let bazs = a.bazs;

虽然这不是:

let a: Foo = Foo {
    bar: "bar".to_string(),
    bazs: vec!["baz_1".to_string(), "bax_2".to_string()],
};

let b = a.bar;
let new_a = a;

你会看到的

error[E0382]: use of partially moved value: `a`
partial move occurs because `a.bar` has type `std::string::String`,
which does not implement the `Copy` trait
© www.soinside.com 2019 - 2024. All rights reserved.