无法保存/传递父级对组合对象的引用

2023-12-10

在 C++ 中,它会是这样的struct A由...组成struct B和一些功能B获取指向父对象的指针A。所以函数为A调用该函数B将简单地通过this指向它的指针。我正在 Rust 中尝试此操作,但未能使其正常工作 - 这就是我想要实现的目标:

struct A<Type: T> {
    composition: Type,
    value: usize,
}

impl<Type> A<Type> where Type: T {
    fn new(obj: Type) -> A<Type> {
        A {
            composition: obj,
            value: 999,
        }
    }

    fn f(&mut self) {
        println!("Value: {:?}", self.value);
    }

    fn call(&mut self) {
        self.composition.f(&mut self);
    }
}

trait T {
    fn f(&mut self, &mut A<Self>);
}

struct B {
    value: usize,
}

impl B {
    fn new() -> B {
        B { value: 0, }
    }
}

impl T for B {
    fn f(&mut self, parent: &mut A<B>) {
        println!("B::f");
        parent.f();
    }
}

fn main() {
    let objA = A::new(B::new());

    // I want call sequence -> A::call() -> B::f() -> A::f()
    objA.call();
}

请注意,我要求所有函数都具有可变性,尽管在上面的示例中看起来似乎是这样&mut self在大多数函数中参数没有多大意义。 Rust 是如何做到这一点的?


这是行不通的,因为你违反了可变别名要求 - 你试图可变地借用A及其子结构同时:

self.composition.f(self);
// roughtly equivalent to:
let c = &mut self.composition;  // borrow substructure
c.f(self /* borrow self */);

(我已经删除了明确的&mut self因为它是不正确的(因为它给了你&mut &mut A<...>,但它根本不会改变整个画面。)

这是 Rust 框架中的一个自然错误。假设f对该特定组合物的实施X重写composition传递的对象上的字段:

impl T for X {
    fn f(&mut self, a: &mut A<X>) {
        a.composition = create_x_somehow();
    }
}

突然,调用该方法的对象被销毁,并且self已作废!

当然,编译器会阻止你这样做即使你知道你不修改的composition,因为这种知识不能静态编码(特别是考虑到这是一种特征方法,任何有权访问您特征的人都可以实现)。

在这种情况下,你基本上有两种选择:

  • 重新表述问题,使其不再需要这样的架构,或者
  • 使用特殊的语言/库结构来解决此类静态检查。

第二点是关于使用诸如Cell/RefCell(它们是安全的,即不需要unsafe块,但它们可能会在运行时出现恐慌 - 也许这些可以在您的情况下工作),或者,如果没有其他帮助,则放弃原始指针并unsafe代码。但是,坦率地说,第一个选项通常更好:如果您根据编译器强制执行的所有权语义和别名规则来设计代码,那么最终的架构几乎总是具有更好的质量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法保存/传递父级对组合对象的引用 的相关文章

随机推荐

  • tomcat7 - jdbc 数据源 - 这很可能会造成内存泄漏

    当 tomcat 关闭时 我在 catalina out 日志文件中收到以下消息 我正在使用 Tomcat 7 x 和 Tomcat JDBC 数据源 Mar 26 2013 1 17 52 PM org apache catalina l
  • Oracle:在文本字段中使用 IN 子句? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在 oracle 9i 中最好地分割 csv 字符串 我有一些遗留数据VARCHAR2 100 field SUBID具有逗号分隔的数据 empno subid 1 1 3 2 2 18 19 3
  • GUI 中的 Tkinter 函数打印

    我做了一个带有 2 个 api 的程序 显示用户选择的不同城市的天气预报和城市信息 但现在我需要帮助 因为我陷入了如何让我的 make request make requests 和 city data 在 GUI 中打印信息的困境 我想我
  • 将 fiddler 会话导出为 .jmx 以用于 JMeter 测试计划

    是否有任何选项 解决方法可以将 fiddler 跟踪文件导出为 jmx 文件以导入到 JMeter 中 看看这个 http www perftesting co uk creating jmeter test plans with fidd
  • 在 Xcode 上找不到框架 FirebaseInstanceID

    我从 Xcode 收到以下错误 尝试了互联网上的许多解决方案 但没有用 ld framework not found FirebaseInstanceID 我尝试过的解决方案 https stackoverflow com a 312982
  • 对 3D 箭袋函数进行颜色映射

    我使用 Matplotlib 在 python 中创建了一个可爱的 3D 位移矢量场 我对结果很满意 然而 从视觉上看 仅从方向上看位移的大小并不是很容易 python中有没有一种方法可以使用箭头的色标 以便位移的大小更清晰 更明显 这就是
  • WPF 线条、路径..等自定义绘图样式

    在 WPF 中 有一种方法可以修改任何路径的绘制方式Dash Dot序列 假设我想为我正在绘制的任何路径或绘图路径本身上的小三角形 波浪等绘制一条三重线 我已经尝试过刷子 但它不会遵循Path 请帮忙 thx WPF s Geometry类
  • ChunkedInput 在球衣中不起作用

    任何人都可以帮助我为什么java代码有问题并一次性打印所有数据而不是将每个块打印为javascript代码 Java代码 import org glassfish jersey client ChunkedInput import java
  • chatDidReceiveMessage 方法未调用 QuickBlox

    我在用QuickBlox iOS SDK用于聊天 登录 注册工作正常 我也可以发送消息 但委托方法 void chatDidReceiveMessage QBChatMessage message 没有接到电话 这是我用来设置聊天的代码 在
  • 如何向 cmdlet 输出添加一列递增值?

    假设我打电话Get Service并想要分配一个新列ID使用打印递增整数的 cmdlet 输出 以便 ID Status Name DisplayName 0 Running AdobeARMservice Adobe Acrobat Up
  • MAMP PEAR 配置指向本地目录

    我正在使用 MAMP 2 0 5 升级 PEAR 时遇到问题 MAMP 如何升级 PEAR 问题是 PEAR 始终安装在 本地 PEAR 目录中 而不是 MAMP PEAR 目录中 我的 MAMP PEAR 配置如下 sudo Applic
  • WordPress MD5 密码

    我需要通过 PHP 脚本或 MySQL 将用户插入到 Wordpress 博客中 并且我有一个纯文本密码 我想我可以做这样的事情 query INSERT INTO new db wp users user login user pass
  • 将word文档解析为excel文件

    我有一个 Word 文档 其中包含我想要解析为 Excel 文件的数据 源文件长达数百页 我一直在使用 VBA 但我刚刚开始学习该语言 并且在尝试输入 doc 文件时遇到了很多困难 我已经能够使用Open和线路输入语句从 txt 文件中检索
  • Python 中动态表单的 Web Scraper

    我正在尝试填写该网站的表格http www marutisuzuki com Maruti Price aspx 它由三个下拉列表组成 一是汽车型号 二是州 三是城市 前两个是静态的 第三个城市是根据州的值动态生成的 有一个 onclick
  • 如果任何字段包含 NULL,MySQL CONCAT 将返回 NULL

    我的表 设备 中有以下数据 affiliate name affiliate location model ip os type os version cs1 inter Dell 10 125 103 25 Linux Fedora cs
  • Google Apps 脚本表单:e.namedValues 不记录任何内容

    我有一个非常基本的 Google Apps 表单 其中包含两个问题 资源 带有两个选项的单选按钮 和名称 文本字段 我想在提交时选择表单值 因此我设置了一个触发器 在表单提交时 来调用函数 function onFormSubmit e L
  • Perl,使脚本在x秒后超时?

    我一直在搜索这个问题 但令人惊讶的是很难得到一个直接的答案 因为 php 似乎有关于这个主题的更多信息 我需要让我的 perl 脚本在指定的秒数后终止 因为 就像现在一样 它们运行时间太长并堵塞了我的系统 我怎样才能使整个脚本在指定的秒数后
  • Java-改变秋千背景颜色?

    好的 我得到了一个使用 系统 外观的 Swing 应用程序 现在 我想将主面板的背景颜色更改为黑色 太容易了吧 UIManager put Panel background Color BLACK 是的 除了现在应用程序中的控件看起来很愚蠢
  • 如何获取 Windows 中所有打开的命名管道的列表?

    有没有一种简单的方法来测试命名管道是否正常工作 我想确保从应用程序发送的数据确实已发送 有没有一种快速简便的方法来获取所有命名管道的列表 在 Windows Powershell 控制台中 键入 System IO Directory Ge
  • 无法保存/传递父级对组合对象的引用

    在 C 中 它会是这样的struct A由 组成struct B和一些功能B获取指向父对象的指针A 所以函数为A调用该函数B将简单地通过this指向它的指针 我正在 Rust 中尝试此操作 但未能使其正常工作 这就是我想要实现的目标 str