限制 Rust 中的对象生命周期

2024-02-10

我正在包装一个 C 库,它有一个标准类型的上下文对象:

library_context* context = library_create_context();

然后使用它你可以创建更多对象:

library_object* object = library_create_object(context);

并摧毁它们:

library_destroy_object(object);
library_destroy_context(context);

所以我把它包装在 Rust 结构中:

struct Context {
    raw_context: *mut library_context,
}

impl Context {
    fn new() -> Context {
        Context {
            raw_context: unsafe { library_create_context() },
        }
    }

    fn create_object(&mut self) -> Object {
        Object {
            raw_object: unsafe { library_create_object(self.raw_context) },
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            library_context_destroy(self.raw_context);
        }
    }
}

struct Object {
    raw_object: *mut library_object,
}

impl Drop for Object {
    fn drop(&mut self) {
        unsafe {
            library_object_destroy(self.raw_object);
        }
    }
}

所以现在我可以这样做,而且它似乎有效:

fn main() {
    let mut ctx = Context::new();
    let ob = ctx.create_object();
}

不过,我也可以这样做:

fn main() {
    let mut ctx = Context::new();
    let ob = ctx.create_object();
    drop(ctx);

    do_something_with(ob);
}

IE。库上下文在它创建的对象之前被销毁。

我可以以某种方式使用 Rust 的生命周期系统来阻止上述代码编译吗?


是的,只需使用正常的生命周期:

#[derive(Debug)]
struct Context(u8);

impl Context {
    fn new() -> Context {
        Context(0)
    }

    fn create_object(&mut self) -> Object {
        Object {
            context: self,
            raw_object: 1,
        }
    }
}

#[derive(Debug)]
struct Object<'a> {
    context: &'a Context,
    raw_object: u8,
}

fn main() {
    let mut ctx = Context::new();
    let ob = ctx.create_object();
    drop(ctx);

    println!("{:?}", ob);
}

这将失败

error[E0505]: cannot move out of `ctx` because it is borrowed
  --> src/main.rs:26:10
   |
25 |     let ob = ctx.create_object();
   |              --- borrow of `ctx` occurs here
26 |     drop(ctx);
   |          ^^^ move out of `ctx` occurs here

有时人们喜欢使用PhantomData https://doc.rust-lang.org/std/marker/struct.PhantomData.html,但我不确定我在这里看到了好处:

fn create_object(&mut self) -> Object {
    Object {
        marker: PhantomData,
        raw_object: 1,
    }
}

#[derive(Debug)]
struct Object<'a> {
    marker: PhantomData<&'a ()>,
    raw_object: u8,
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

限制 Rust 中的对象生命周期 的相关文章

随机推荐

  • 是否有更易读或 Pythonic 的方式将 Decimal 格式化为 2 位?

    将小数固定到两位的语法到底是怎么回事 gt gt gt from decimal import Decimal gt gt gt num Decimal 1 0 gt gt gt num quantize Decimal 10 2 seri
  • 无需在 go 中阅读即可查看 Conn

    我有一个服务器net Conn 我想在读出字节之前先查看一下它 以检查它是否是客户端尝试使用的纯文本协议或 SSL TLS 检查http golang org pkg net http golang org pkg net 看来Conn接口
  • 如何使用 mvc4 C# 在 linq toEntity 预加载中包含多个表

    我有 6 节课 我尝试使用linq到实体以获得SiglaUF最后一个更深层次的表的信息 在视图 MVC 中 问题是我收到以下错误 ObjectContext 实例已被处置 不能再用于需要连接的操作 视图是这样的 gt model IEnum
  • 数组中元素的确切最大限制是多少

    这是一个纯粹的理论问题 所以请不要在你的答案中警告我这一点 如果我没记错的话 因为 NET 中的每个数组都由Int32 意味着索引范围为0 to Int32 MaxValue 假设不涉及内存 GC 约束 NET 中的数组最多可以有21474
  • 如何将原始 html 文件添加到 create-react-app 中的公共文件夹

    我有一个使用 create react app 创建的 React 应用程序 我已经公开了一个静态 html 页面 我想在使用 iframe 的同一应用程序中使用该 html 构建后 带有 covid html 的 iframe 不会加载
  • jquery 延迟链接被跟踪

    我有一个基于 css 的简短动画 我想在链接之前播放它 一张在页面加载时突然进入的卡片在单击后突然弹出 然而 目前 调用的页面加载速度太快 我希望能够短暂延迟 href 的跟踪 这是我所得到的 document ready function
  • 计算两个地理点之间的最短路径?

    我是 Java 和 Android 新手 我需要找到两个路径点之间的最短路径 我一整天都在寻找答案 我刚刚得到了这个代码 var directionDisplay var directionsService new google maps
  • 应用程序更新后小部件消失了

    更新我的应用程序后 有时所有旧的小部件都会从主屏幕上消失 在应用程序启动器 小部件选择器中 我的三个小部件出现两次 直到重新启动 有什么建议么 在本页 https medium com the wtf files the mysteriou
  • 在 pandas 数据帧上使用 scipy NonlinearConstraint 求解非线性方程

    我正在尝试求解方程组 其中 a b 和 c 是 pandas 数据框中的列 我曾经使用 Excel 在其中运行宏 通过更改其他列 函数 的值来在一列 残差 中进行查找 但我不知道如何在Python中做到这一点 我已经问过here https
  • 指定 Flexbox Flex 项目的宽度:宽度还是基础? [复制]

    这个问题在这里已经有答案了 假设我正在做 3 个弹性列 第一个 50 另外两个自动调整 half flex 0 0 auto width 50 or half flex 0 0 50 这些似乎在功能上是相同的 他们是吗 底部语句相当于 ha
  • 如何将 Python 捆绑到 macOS .app 应用程序中?

    我有一个用 python 编写的软件 带有用 PyQt 编写的图形用户界面 为了创建该软件的可执行文件 我附带了一个 Python 和 Qt 预编译版本 这个技巧似乎在 Windows 和 Linux 中都有效 因为我知道如何创建安装程序
  • 在 Storyboard 中切换 UINavigationController 堆栈的最佳实践

    在我们的故事板中 我们有多个UINavigationController堆栈 例如 LoginViewController堆栈完全独立于SWRevealViewController stack 在它们之间切换的最佳实践是什么 当我按下注销按
  • 使用 MotionEvent.ACTION_MOVE 制作像主屏幕一样的 ViewFlipper

    好的 我有一个ViewFlipper与三个LinearLayouts嵌套在其中 它默认显示第一个 这段代码 Assumptions in my Activity class oldTouchValue is a float vf is my
  • 如何伪造ajax文件上传?

    我有一个上传表单 我想填充一个文件 特别是图像 我的理解是我需要创建一个 File 对象来放入相对形式的 FileList 中 目前我拥有的图像采用数据 URI 格式 data image png base64 但我可以更改它 如果这是真的
  • Spring 模型对象未渲染

    我试图从某些 JSP 页面上的控制器返回消息字符串作为模型对象 成功 jsp 但该消息未在目标页面上呈现 这是我在页面上得到的内容 成功 jsp 欢迎 消息 这是 JSP 页面返回的控制器方法 RequestMapping value re
  • Chrome 消息传递:chrome.runtime.sendMessage 在最新版本 49 上不起作用

    我有一个 Chrome 扩展程序 在版本 48 上运行得很好 但由于某种原因 在版本 49 上无法运行 并且无法在其发布 更改日志中找到任何内容 不起作用的部分是消息传递 背景页 chrome runtime onMessage addLi
  • 可以用 PHP 连接到远程桌面吗?

    我有一些服务器 我想经常连接它们来运行程序 然而 为了使它更容易 我想让一个 PHP 脚本通过远程桌面连接到它们中的每一个并运行它们中的每一个 这可能吗 如果是这样 我应该从哪里开始 举个例子就太好了 理论上 您可以实现一个可以通过 RDP
  • 无法在 Visual Studio 2019 中使用 Azure Function 项目构建 docker compose

    我尝试将 Azure Function 项目添加到在 Visual Studio 2019 16 7 6 中创建的 docker compose 文件中 但这会导致解决方案无法构建 Docker for Windows 2 4 0 0 48
  • 如何在 python 中正确使用 unicode 字符以避免出现错误?

    我正在为 Google 快速搜索框开发一个 python 插件 它对非 ascii 字符做了一些奇怪的事情 看起来代码工作得很好 直到我尝试构造一个包含非 ASCII 字符的字符串 是我的测试字符 我使用以下代码片段进行构建 其中 new
  • 限制 Rust 中的对象生命周期

    我正在包装一个 C 库 它有一个标准类型的上下文对象 library context context library create context 然后使用它你可以创建更多对象 library object object library c