我想在rust中创建一个小型解析器,它可以解码几种类型->数字,字符串,列表等。例如,列表可以包含任何类型->其他列表,数字等
我有一个超级特征'Element',它将成为我所有类型的基础。然后每种类型都有一个特征,所有特征都需要'Element'特征。这些特征得到一些具体结构的支持。由于列表可以包含(混合)任何类型,因此我尝试将值存储为Vec<Box<dyn Element>>
。问题是,稍后我尝试将dyn Element
转换为其他特征时,碰壁了:
error[E0161]: cannot move a value of type dyn Element: the size of dyn Element cannot be statically determined
--> src/main.rs:94:27
|
94 | let boxed_as_number = num_as_element.to_boxed_number();
| ^^^^^^^^^^^^^^
use std::fmt;
pub enum ElementType {
Number,
Text,
}
pub trait Element: fmt::Debug {
fn element_type(&self) -> ElementType;
// Works, but I do not want a reference -> I want to change the "type"
fn to_number_ref(&self) -> Option<&dyn Number>;
fn to_boxed_number(self) -> Option<Box<dyn Number>>;
}
pub trait Number: Element {
fn value(&self) -> i64;
}
pub trait Text: Element {
fn value(&self) -> &str;
}
#[derive(Debug)]
pub struct SignedNumber {
value: i64
}
impl SignedNumber {
fn new(value: i64) -> SignedNumber {
return SignedNumber { value };
}
}
impl Element for SignedNumber {
fn element_type(&self) -> ElementType {
return ElementType::Number;
}
fn to_number_ref(&self) -> Option<&dyn Number> {
return Some(self);
}
fn to_boxed_number(self) -> Option<Box<Number>> {
return Some(Box::new(self));
}
}
impl Number for SignedNumber {
fn value(&self) -> i64 {
return self.value;
}
}
#[derive(Debug)]
pub struct StringWrapper {
value: String
}
impl StringWrapper {
fn new<T: Into<String>>(value: T) -> StringWrapper {
return StringWrapper { value: value.into() };
}
}
impl Element for StringWrapper {
fn element_type(&self) -> ElementType {
return ElementType::Text;
}
fn to_number_ref(&self) -> Option<&dyn Number> {
return None;
}
fn to_boxed_number(self) -> Option<Box<Number>> {
return None;
}
}
impl Text for StringWrapper {
fn value(&self) -> &str {
return &self.value;
}
}
fn main() {
let num = SignedNumber::new(1);
let num_as_element: Box<dyn Element> = Box::new(num);
let borrowed_as_num = num_as_element.to_number_ref().unwrap();
let num = SignedNumber::new(2);
let num_as_element: Box<dyn Element> = Box::new(num);
let boxed_as_number = num_as_element.to_boxed_number();
}
在这种情况下,self
是否应该SignedNumber
?为什么rustc认为它是dyn Element
?
impl Element for SignedNumber {
fn to_boxed_number(self) -> Option<Box<Number>> {
return Some(Box::new(self));
}
}
是否可以进行这种类型转换,还是应该坚持引用?