如何删除(移出)包含大数据结构类型的结构体字段?

Nur*_*yev 3 rust

我有一个非常大的结构:

struct VeryLargeStructure {
    // many tens of fields here
}
Run Code Online (Sandbox Code Playgroud)

另一个结构体将其包含在字段中:

struct A {
  v: VeryLargeStructure 
}
Run Code Online (Sandbox Code Playgroud)

我如何从v现场转移价值......

let a = A{/* ... */}
let b = a.v;
Run Code Online (Sandbox Code Playgroud)

...无需为 构造一个新的 VeryLargeStructure 实例,因为a.v这会导致性能不佳且无用?

我知道mem::replacemem::swap,但它们不满足上述要求。

我更喜欢安全的方法,但我怀疑没有一种方法,所以我也准备采取一种unsafe方法。

SCa*_*lla 6

顺便说一句,你已经写的东西是有效的。这会将所有权转移a.vb无效a(旧变量不再存在)。这意味着我们不需要用有效数据替换我们取出的数据。这是拥有所有权相对于仅仅可变访问的好处之一。

let a = A {
    v: VeryLargeStructure {/* ... */},
};
let b = a.v;
// Now `b` has ownership of what was once `a.v`.
// `a` no longer exists as a single entity,
// but you could extract other fields too if you wish.
// E.g. `let c = a.w` if `w` is some other field of `a`.
Run Code Online (Sandbox Code Playgroud)

在上下文中,

struct VeryLargeStructure {
    // many tens of fields here
}

struct A {
    v: VeryLargeStructure,
}

fn main() {
    let a = A {
        v: VeryLargeStructure {/* ... */},
    };
    let b = a.v;
}
Run Code Online (Sandbox Code Playgroud)

(操场)


这个稍微脱糖的版本是解构。它可用于轻松地一次提取多个字段。不过,对于单个字段来说,let b = a.v;可能是首选,因为它更简单、更清晰。

struct VeryLargeStructure {
    // many tens of fields here
}

struct A {
    v: VeryLargeStructure,
}

fn main() {
    let a = A {
        v: VeryLargeStructure {/* ... */},
    };
    let A { v: b } = a;
}
Run Code Online (Sandbox Code Playgroud)

(操场)


请注意,如果A实现Drop,它必须保留其所有字段的所有权。这意味着您永远无法在不更换的情况下搬出它。不过,替换数据(例如用mem::replace)是可以的。

  • @NurbolAlpysbayev 不。是的,所有内容都会被删除(除了某些特殊情况),但默认情况下,结构会递归删除。这会独立地删除字段,因此它们不必全部完好无损。不过,实现“Drop”可以覆盖它。由于“drop”方法在删除对象之前可以(可变)访问该对象,因此所有字段都需要完好无损。尝试使用答案中添加了“impl Drop for A {fn drop(&mut self) {}}”的代码来查看错误。 (2认同)