gpt4 book ai didi

rust - rust 特质问题特质不能制成对象

转载 作者:行者123 更新时间:2023-12-03 11:47:33 27 4
gpt4 key购买 nike

我正在尝试编写一些代码,该代码将生成具有随机值的随机结构。对于结构,我具有以下特征和帮助程序宏:

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对象上使用它,但听起来您可能不想这样做。)

关于rust - rust 特质问题特质不能制成对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64495740/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com