如何破坏/脱离实施类型?

发布于 2025-01-30 08:37:14 字数 927 浏览 1 评论 0 原文

我有一个托管指针类型 uniq ,实现 drop ,该方法应在不运行 drop 的情况下消耗它,然后返回其分配的。

struct Uniq<T> { data: ManuallyDropped<Box<T>>, metadata: Metadata }

impl Uniq<T> {
   fn into_parts(/* mut */ self) -> (Box<T>, Metadata) {
     (ManuallyDrop::into_inner(self.data), self.metadata) // doesn't work

     // let Self { data, metadata } = self; // doesn't work either
   }
}

impl<T> Drop for Uniq<T> {
  fn drop(&mut self) {
    // fancy_management_ledgerwork(self.metadata)
  }
}

#[derive(Clone, Copy)]
struct Metadata(usize);

我如何为我的类型完成这种“破坏性移动”,哪种实现 drop

注意:从字面上看,每个搜索引擎的结果都是关于人们不了解移动语义。我 do 了解移动语义,我正在尝试利用它们以确保记忆安全,我无法弄清楚如何。我宁愿不要将 ManallyDrop&lt; box&lt; t&gt;&gt; 转换为较少安全的东西,复制喜欢 nonnull&lt; t&gt;

I have a managed pointer type Uniq, implementing Drop, that has a method that is supposed to consume it without running drop and return a Box of its allocation.

struct Uniq<T> { data: ManuallyDropped<Box<T>>, metadata: Metadata }

impl Uniq<T> {
   fn into_parts(/* mut */ self) -> (Box<T>, Metadata) {
     (ManuallyDrop::into_inner(self.data), self.metadata) // doesn't work

     // let Self { data, metadata } = self; // doesn't work either
   }
}

impl<T> Drop for Uniq<T> {
  fn drop(&mut self) {
    // fancy_management_ledgerwork(self.metadata)
  }
}

#[derive(Clone, Copy)]
struct Metadata(usize);

How do I accomplish this kind of "destructuring move" for my type which implements Drop?

Note: Literally every search engine result is about people not understanding move semantics. I do understand move semantics and I am trying to exploit them to ensure memory safety and I cannot figure out how. I'd rather not convert the ManuallyDrop<Box<T>> to something less-safe-but-Copy like NonNull<T>.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拿命拼未来 2025-02-06 08:37:14

使用

fn into_parts(mut self) -> (Box<T>, Metadata) {
    (unsafe { ManuallyDrop::take(&mut self.data) }, self.metadata)
}

编辑: @filiperodrigues正确地提到,如果您的 drop 实现尝试进行清理,您还需要防止其运行,要么通过 std :: mem :: best()或通过 self 手动drop 中包装。

Use ManuallyDrop::take():

fn into_parts(mut self) -> (Box<T>, Metadata) {
    (unsafe { ManuallyDrop::take(&mut self.data) }, self.metadata)
}

Edit: As correctly mentioned by @FilipeRodrigues, if your Drop implementation tries to do cleanup you also need to prevent it from running, either by std::mem::forget() or by wrapping self in ManuallyDrop.

甜是你 2025-02-06 08:37:14

此编译:

use std::mem::ManuallyDrop;

struct Uniq<T> { data: ManuallyDrop<Box<T>>, metadata: Metadata }

impl<T> Uniq<T> {
   fn into_parts(/* mut */ self) -> (Box<T>, Metadata) {
     (ManuallyDrop::into_inner(self.data), self.metadata)
   }
}

// impl<T> Drop for Uniq<T> {
//   fn drop(&mut self) {
//     // fancy_management_ledgerwork(self.metadata)
//   }
// }


#[derive(Clone, Copy)]
struct Metadata(usize);

This compiles:

use std::mem::ManuallyDrop;

struct Uniq<T> { data: ManuallyDrop<Box<T>>, metadata: Metadata }

impl<T> Uniq<T> {
   fn into_parts(/* mut */ self) -> (Box<T>, Metadata) {
     (ManuallyDrop::into_inner(self.data), self.metadata)
   }
}

// impl<T> Drop for Uniq<T> {
//   fn drop(&mut self) {
//     // fancy_management_ledgerwork(self.metadata)
//   }
// }


#[derive(Clone, Copy)]
struct Metadata(usize);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文