Rust 特征问题 特征不能变成对象

2024-06-21

我正在尝试编写一些代码来生成具有随机值的随机结构。我有以下结构的特征和辅助宏:

use rand::{thread_rng, Rng};
use std::fmt;

pub trait DataType {
    /// generate a new instance of the type with a random value
    fn random() -> Box<Self>;
    /// generate a new instance of the same type with a random value
    fn gen_another(&self) -> Box<Self>;
}

macro_rules! impl_data_type_for_num {
    ($x:ident) => {
        impl DataType for $x {
            fn random() -> Box<Self> {
                Box::new(Self {
                    value: thread_rng().gen()
                })
            }

            fn gen_another(&self) -> Box<Self> {
                Self::random()
            }
        }
    };
}

macro_rules! impl_formatting {
    ($x:ident, $s:expr) => {
        impl fmt::Debug for $x {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, $s)
            }
        }

        impl fmt::Display for $x {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{}", self.value)
            }
        }
    };
}

然后我使用宏在一堆结构上实现所需的特征(以下是一些示例):

pub struct VirtBool {
    value: bool
}
impl_data_type_for_num!(VirtBool);
impl_formatting!(VirtBool, "bool");

pub struct VirtU8 {
    value: u8
}
impl_data_type_for_num!(VirtU8);
impl_formatting!(VirtU8, "u8");

pub struct VirtU16 {
    value: u16
}
impl_data_type_for_num!(VirtU16);
impl_formatting!(VirtU16, "u16");

到目前为止,一切正常,但是当我尝试在具有未调整大小的字段的结构上实现相同的特征时,出现了一个问题:

pub struct VirtArray {
    _type: Box<dyn DataType>,
    value: Vec<Box<dyn DataType>>
}
impl DataType for VirtArray {
    fn random() -> Box<Self> {
        let t = random_var();
        let s = thread_rng().gen_range(0, 10);
        Box::new(Self {
            _type: *t,
            value: (0..s).map(|_| t.gen_another()).collect()
        })
    }

    fn gen_another(&self) -> Box<Self> {
        Box::new(Self {
            _type: self._type,
            value: self.value.iter().map(|t| t.gen_another()).collect::<Vec<Box<dyn DataType>>>()
        })
    }
}
impl fmt::Debug for VirtArray {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}; {}]", self._type, self.value.len())
    }
}
impl fmt::Display for VirtArray {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut s = self.value.iter().map(|v| format!("{}, ",v)).collect::<String>();
        s.truncate(s.len().checked_sub(2).unwrap_or(s.len()));
        write!(f, "[{}]", s)
    }
}

这会引发错误the trait 'DataType' cannot be made into an object有好几次。然后我有一个函数来创建一个随机结构,但这也会引发相同的错误:

/// generate a random type with random value
fn random_var() -> Box<dyn DataType> {
    match thread_rng().gen_range(0,4) {
        0  => Box::new(VirtBool::random()),
        1  => Box::new(VirtU8::random()),
        2  => Box::new(VirtU16::random()),
        3  => Box::new(VirtArray::random()),
        _  => panic!("invalid")
    }
}

我最初使用枚举来完成所有这些操作,但我尝试将其切换为结构和特征以帮助扩展/使用能力。有谁知道如何修复上面的代码?我在这里遇到障碍已经有一段时间了。

另外,我知道我可以使用type_name_of_val打印类型,但我试图避免使用不稳定/夜间功能。


DataType不能制作成特征对象,因为它使用Self因为它有一个静态方法。

我意识到这似乎像是回归Box<Self>可能是合理的要求dyn DataType,因为如果你调用它dyn DataType你想要一个Box<dyn DataType>,但是 Rust 不会尝试修改方法来让你返回返回的方法,例如Box<VirtArray>进入那些返回的Box<dyn DataType>如果他们被叫去dyn DataType价值。您可以通过让方法返回来解决此问题Box<dyn DataType>反而。

特征对象不允许使用静态方法,因为特征对象类型没有实现。记住,dyn Foo实施Foo。什么会(dyn DataType)::random()是? (您可以使用 where 子句,如上例所示,以确保dyn DataType预计不会以可以提前检测到的方式拥有此方法;这意味着您不能在您的dyn DataType对象,但听起来您可能不想这样做。)

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

Rust 特征问题 特征不能变成对象 的相关文章

随机推荐

  • Solr:在哪里可以找到 Luke 请求处理程序

    我正在尝试获取 Solr 索引中所有静态和动态字段的列表 另一个SO答案 https stackoverflow com a 16296974 765287建议为此使用 Luke 请求处理程序 它建议在此 url 中查找处理程序 http
  • python sqlite“开始事务”和“提交”命令

    如果我想通过 python 在数据库中启动事务 我必须像这样显式执行 sql 命令 BEGIN TRANSACTION import sqlite3 conn sqlite3 connect db c conn cursor c execu
  • 对原型绑定感到困惑,这个声明

    在下面的代码中 我想知道上下文如何绑定到this In obj myMethod 上下文被赋予对象 因此记录它会给出对象 In var myFun obj myMethod then myFun 上下文被赋予窗口 唯一的区别是您将函数设置为
  • 如何保留超过 5 天的查询日志?

    在 Redshift 中 有一个STL QUERY存储过去 5 天运行的查询的表 我正在尝试找到一种方法来保存超过 5 天的记录 以下是我考虑过的一些事情 有红移设置吗 看来不是 我可以使用触发器吗 Redshift 中不提供触发器 因此这
  • 类库的 app.config 中的绑定重定向有什么作用吗?

    我经常使用的 VS 解决方案包括单个可执行项目 控制台应用程序 网络应用程序 和许多类库项目这些都被可执行文件引用 使用 NuGet 并安装包时 经常会出现app config为每个项目创建的文件 通常只包含合并引用程序集版本的绑定重定向列
  • scala 贷款模式,可选函数参数

    我有一个贷款模式 该模式应用函数 n 次 其中 i 是递增变量 偶尔 我希望传入的函数能够访问 i 但我不想要求传入的所有函数都需要定义一个参数来接受 i 下面的例子 def withLoaner n Int gt op Int gt St
  • Jquery在quote中设置引号

    我有这样的代码 input id id slice 0 1 br brand qnt to cart show 这产生了我 input id 02620 br FEBI BILSTEIN qnt to cart 但我需要看到类似的东西 in
  • PHP表单提交后如何显示成功消息?

    这是代码 我想要这样 表单提交 gt page2 php gt 重定向 gt page1 php 这是消息 弹出窗口或其他内容 page1 php
  • Excel VBA:声明通用对象与指定对象类型之间的区别

    我发现使用声明为的变量出现了意外的 至少对我来说 行为Object在 Excel vba 中 我试图从 html 页面中提取一些数据 所以我使用了这样的例程 sub Test Dim htmlPage As htmlDocument Thi
  • 如何关闭 RStudio 中的突出显示环绕行为?

    我已经搜索过这个问题 很可能我只是想不出正确的搜索词 所以如果这个问题已经被问到并得到回答 我深表歉意 我还检查了 RStudio 选项 在 RStudio 中 如果突出显示某个单词 然后键入单引号 双引号或括号 它会将该单词包含在该字符中
  • yii2 将 JS 文件注册到视图

    我有 A php 视图文件 views A 文件夹 我有 A js js 文件 views A 文件夹 请帮我在视图文件中注册js文件 据我了解 我必须写 this gt registerJsFile path to file js 在视图
  • 仅 HTTP 支持跨源请求,但不支持跨域

    我使用此代码发出 AJAX 请求 userBarSignup click function get C xampp htdocs webname resources templates signup php params function
  • “canvas.toDataURL(“image/png”)”在 Firefox 中无法正常工作

    我有一个带有文件输入字段的网页 我想 上传图像文件 使用上传的图像创建图像元素 把它画在画布上 获取画布的 DataURL 此过程适用于 Google Chrome 但不适用于 Mozilla Firefox 当我 console log
  • 使用Qt5的QWebEngine

    14784 PyInstaller Bootloader 3 x 14784 LOADER executable is C Users Desktop Papinhio player exe dist Papinhio player exe
  • 使用 @Inheritance(strategy=InheritanceType.JOINED) 与实体进行 JPA 一对多关联

    大家好 我正在尝试将一对多关联映射到映射的实体 Inheritance strategy InheritanceType JOINED ManyToMany JoinTable name S MC CC CONTRATTIRAPPORTI
  • 如何将 JSON 转换为 Scala 中的类型

    我的问题是我收到来自 twitter 的 JSON 文本 然后我想将此文本转换为 scala 中的本机对象 有标准方法可以做到这一点吗 我也在用Play 2 这是我所拥有的 import scala io Source fromInputS
  • 组内 STRING_AGG 和 Visual Studio 的问题

    我正在使用 Visual Studio 2015 并且我的 SQL Server 数据库项目中的 STRING AGG Within GROUP 出现问题 SELECT Continent STRING AGG Country WITHIN
  • 数组到集合:优化代码

    有更好的方法来实现这一目标吗 public static List
  • 为什么我需要 2 个或更多核心数据模型?

    我很想知道谁使用多个核心数据模型以及为什么 有什么好处 我正在开发一个应用程序 我认为我可以从多个模型中受益 但我不确定其他好处 我即将推出的应用程序将适用于 iPad 和 iPhone 的另一个版本 iPad 有 3 个主要内容 iPho
  • Rust 特征问题 特征不能变成对象

    我正在尝试编写一些代码来生成具有随机值的随机结构 我有以下结构的特征和辅助宏 use rand thread rng Rng use std fmt pub trait DataType generate a new instance of