在 Rust 中使用枚举实现动态多态性

2023-11-22

当人们已经知道某些需要动态多态性的代码中涉及的所有有限数量的类型时,使用enum与使用相比,可以更好地提高性能Box因为后者使用动态内存分配,并且您需要使用也具有虚拟函数调用的特征对象。

也就是说,与 C++ 中使用的等效代码相比std::variant and std::visit,看起来这个场景中的 Rust 涉及更多样板代码,至少对我来说是这样(我还没有学会使用过程宏)。在这里举个例子:我有很多struct types:

struct A {
    // ...
}

struct B {
    // ...
}

// ...

struct Z {
    // ...
}

他们都实现了特质AlphabetLetter这是:

trait AlphabetLetter {
    fn some_function(&self);
}

由于涉及的类型集是已知且有限的,我想使用enum:

enum Letter {
    AVariant(A),
    BVariant(B),
    // ...
    ZVariant(Z),
}

这里我们已经有了第一个样板:我需要添加一个名称enum涉及的每个类型变体的值。但真正的问题是:enum Letter本身就是一个AlphabetLetter,它只是代表了这样一个事实:我们在运行时不知道它是哪个字母。所以我开始为它实现这个特质:

impl AlphabetLetter for Letter {
    fn some_function(&self) {
        match self {
            Letter::AVariant(letter) => letter.some_function();
            Letter::BVariant(letter) => letter.some_function();
            // ...
            Letter::ZVariant(letter) => letter.some_function();
        }
    }
}

是的,这可以很容易地变成很多代码,但我发现没有其他方法可以做到这一点。在 C++ 中,多亏了泛型 lambda,人们可以std::visit a std::variant这是单行船。我怎样才能做到同样的事情,而不需要手动为特征 X 中的每个变体中的每个函数编写所有模式匹配enum?


您可以通过示例使用宏(而不是过程宏)来避免样板代码:

macro_rules! make_alphabet {
    ($($x:ident),*) => {
        enum Letter {
            $(
                $x($x),
            )*
        }

        impl AlphabetLetter for Letter {
            fn some_function(&self) {
                match self {
                    $(
                        Letter::$x(letter) => letter.some_function(),
                    )*
                }
            }
        }
    };
}

然后你调用它来生成所有内容:

make_alphabet!(A, B, C, ..., Z);

现在您可以随时访问它letter: Letter:

letter.some_function();

对于不需要对所有变体进行操作的方法,您可以使用impl外部。

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

在 Rust 中使用枚举实现动态多态性 的相关文章

随机推荐

  • 如何使用闹钟类设置闹钟

    您好 我正在尝试使用 AlarmClock 类在我的应用程序中设置闹钟 我使用的代码如下 Intent intent new Intent intent setAction AlarmClock ACTION SET ALARM start
  • 创建新的 Microsoft.CodeAnalysis.CustomWorkspace - 出现 ReflectionTypeLoadException

    我尝试在 NET 编译器平台 Roslyn 示例中创建类似 ConsoleClassifier 的内容 Microsoft CodeAnalysis v0 7 此时我得到了ReflectionTypeLoadException Custom
  • 从 URL 加载时应如何处理视网膜/普通图像?

    我了解如何以编程方式从 URL 为我的应用程序加载图像 而不是将它们打包在应用程序中 但如何处理 1x 与 2x 问题 如果需要 我可以从外部源提供这两个版本 但是在设置 UIImage 时如何处理 我很确定您无法以自动方式远程加载 2x
  • 使用 Node.js 作为简单的 Web 服务器

    我想运行一个非常简单的 HTTP 服务器 每个 GET 请求example com应得index html提供给它 但作为常规 HTML 页面 即 与阅读普通网页时的体验相同 使用下面的代码 我可以读取内容index html 我如何服务i
  • 带有片段或活动的 Android Studio 导航抽屉

    我正在尝试使用 Android Studio 的导航抽屉模板开发一个应用程序 因此 我使用此模板创建了一个新项目 但是当我运行程序并单击菜单项时 视图不会改变 我在互联网上到处搜索 但我不知道如何处理这个问题 这是Android Studi
  • libxslt 是否具有将一个文档拆分为多个文档的功能?

    看起来 libxslt 不支持 XSLT 2 0 并且xsl result document 有没有办法模仿xsl result document using libxslt or xsltproc 是的 有 使用exsl 文档 一个简单的
  • JPA 标准中具有复合主键的 IN 子句

    我有一个名为group tableMySQL 中只有两列user group id and group id 它们都是类型VARCHAR 这两列一起形成一个复合主键 我需要使用子选择执行语句IN 根据传递给查询的值列表选择行 Overrid
  • CakePHP 安全

    我是网络应用程序安全性的新手 我正在 Cakephp 中开发一个应用程序 我的一位朋友告诉我有关跨站点请求伪造 CSRF 和跨站点脚本 XSS 攻击等的信息 但不确定还有多少 我需要一些帮助来了解如何让 Cakephp 保护我的网络应用程序
  • 文本对齐:对齐和图像

    我有一个图像列表 不在列表中 但如果可以解决问题的话可能是 我想填充 div 的整个宽度 我已经尝试过底部的代码 虽然它确实证明了 p 标记中的任何文本合理 但它对图像的作用却不同 我怎样才能让它在 div 的整个宽度上均匀地间隔图像 di
  • 从数据库填充 DropDownList 的正确方法是什么?

    我正在从 SQL Server 数据库填充 DropDownList 如下所示 它工作得很好 但我不确定这是一个好方法 有人可以阐明这种方法并进行一些改进吗 private void LoadSubjects ddlSubjects Ite
  • Android Gradle 代码覆盖率

    我有一个带有测试用例的简单 Android 项目 ProjNameProject build gradle ProjName build gradle 我看到默认情况下android的新构建系统默认提供基本的测试结果 万岁 现在我还想查看代
  • 错误 - 多次出现具有不同值的“contentType”是非法的

    我在 Eclipse 中有一个动态 Web 项目 在 Glassfish4 上运行 在项目中 有一个如下所示的index jsp文件 当我在服务器上运行这个jsp时 出现错误 org apache jasper JasperExceptio
  • 在Windows上构建hadoop 2.2

    我正在尝试在windows上安装hadoop 到目前为止还很麻烦 这是我不断收到的错误 ERROR Failed to execute goal org codehaus mojo exec maven plugin 1 2 exec co
  • 我可以使用 Laravel 5 中间件来允许包覆盖应用程序路由吗?

    我希望能够使用包中的路由覆盖 app Http routes php 中定义的路由 例如 在 app Http routes php 中我可能有这个 Route get search type as gt search uses gt Se
  • 如何在没有科学记数法的 R 数据框中显示数字列('e+07')

    我有一个 R 数据框 其中一列包含一串数字 但我想将它们视为一个因素 主要是为了阻止 R 使用 e 04 等缩短数字 我发现解决此问题的一种方法是编辑从中获取数据的 csv 文件 并添加一个在所需列中包含单词的虚拟条目 然后重新导入它 如何
  • 如何将 facebook、twitter 和 google plus 集成到 Android 应用程序中

    我喜欢将 Facebook Twitter 和 Google plus 集成到我的应用程序中 以便使用该应用程序的用户可以更新他们的状态 因此我想知道如何做到这一点 Thanks 我强烈建议不要使用这些 SDK 因为它们包含很多错误 而且据
  • 如何获取默认 NIC 连接名称

    重要编辑 再次回到这个话题 正如您所说不应该有默认的网卡 我试图了解是否有一种方法可以检测实际连接的所有网卡 有了我的物理接口的 MAC 地址 是否有一种编程方式来获取接口名称 接口状态 等 比如我的XP机器 设备 Realtek RTL8
  • 自动递增 bigint 列?

    我想要插入表中的每一行数据都有一个 bigint ID 列 我想要 Sql 服务器生成数字 我尝试创建一个具有 bigint 列 ID 的表 我希望这是自动增量 第一个值为 1 我尝试使用 ID bigint AUTO INCREMENT
  • 将数据从 Props 传递到 vue.js 中的数据

    我有以下 vue 组件
  • 在 Rust 中使用枚举实现动态多态性

    当人们已经知道某些需要动态多态性的代码中涉及的所有有限数量的类型时 使用enum与使用相比 可以更好地提高性能Box因为后者使用动态内存分配 并且您需要使用也具有虚拟函数调用的特征对象 也就是说 与 C 中使用的等效代码相比std vari