gpt4 book ai didi

rust - 如何从实现 Drop 的结构中移动类型未实现 Default 的字段?

转载 作者:行者123 更新时间:2023-12-03 11:27:01 25 4
gpt4 key购买 nike

有一些similar questions ,但是 the answers要求字段实现 Default 或以某种方式用字段类型初始化另一个值。

我们有一个 Node其中有一个 value类型 T :

struct Node<T> {
value: T,
next: Option<Box<T>>
}
它有一个方法可以移动 value来自 Node :
impl<T> Node<T> {
fn value(self) -> T {
self.value
}
}
上面的代码编译通过。但是如果我们执行 DropNode :
impl<T> Drop for Node<T> {
fn drop(&mut self) {}
}
然后我们会得到一个编译错误:
error[E0509]: cannot move out of type `Node<T>`, which implements the `Drop` trait
| self.value
| ^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `self.value` has type `T`, which does not implement the `Copy` trait
我猜它不会编译,因为如果我们实现自定义 Drop ,我们需要确保不掉 value字段,如果下降发生在 value 的末尾方法块。但是,我们无法检查;即使我们可以,编译器也无法静态检查我们是否这样做了。
解决此问题的一种方法是存储 value字段为 Option<T> .但是假设我们不想使用 Option由于某些原因(开销等),
我们还能做些什么来同时拥有自定义 Drop和一个 value移动方法 value field ?
我想我们必须使用一些 unsafe方法,那很好。

Rust Playground

最佳答案

如果不使用 unsafe,我不知道有什么方法可以做到这一点(虽然其他人可能会),但这里有一种方法可以使用 unsafe :

use std::{ptr, mem};

impl<T> Node<T> {
fn value(mut self) -> T {
unsafe {
let v: T = ptr::read(&self.value);
ptr::drop_in_place(&mut self.next);
mem::forget(self);
v
}
}
}
我们使用 ptr::read移出所需的值。然后我们需要使用 mem::forgetNode以确保其 drop不调用方法(否则 value 可能会被删除两次并导致未定义的行为)。防止 next成员(member)从泄漏,我们使用 ptr::drop_in_place运行其 drop方法。
有趣的是,这个安全代码不起作用:
impl<T> Node<T> {
fn value(self) -> T {
match self {
Node {value, next: _} => value
}
}
}
它给出了同样的错误:

error[E0509]: cannot move out of type Node<T>, which implements theDrop trait


我本来希望使用 match表达式获得所有 self 的所有权并将其分解为组件, drop 就没有办法了。被调用 self因此编译器没有理由提示。但显然它不是这样工作的。

关于rust - 如何从实现 Drop 的结构中移动类型未实现 Default 的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62970572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com