我尝试在boxed struct ValuesChangingImpl<T>
中保存struct字段的更改,并使用代码隐藏trait ValuesChanging
下的字段类型:
use std::any::Any;
use std::clone::Clone;
//#[derive(Clone)]
pub enum HistoryItem {
FieldChanging(Box<ValuesChanging>)
// other changing variants
}
pub trait ValuesChanging/*: Clone*/ {
fn get_old_value<T: Any + Clone>(&self) -> &T;
fn get_new_value<T: Any + Clone>(&self) -> &T;
}
pub struct ValuesChangingImpl<T> where T: Any + Clone {
old_value: Box<T>,
new_value: Box<T>
}
impl<T:Any + Clone> ValuesChangingImpl<T> {
pub fn new(old_value: Box<T>, new_value: Box<T>) -> Self {
ValuesChangingImpl {
old_value: old_value,
new_value: new_value
}
}
}
impl<T:Any + Clone> Clone for ValuesChangingImpl<T> {
fn clone(&self) -> Self {
ValuesChangingImpl::new(
self.old_value.clone(),
self.new_value.clone())
}
}
impl<T:Any + Clone> ValuesChanging for ValuesChangingImpl<T> {
fn get_old_value<ValueType: Any + Clone>(&self) -> &ValueType {
self.old_value.downcast_ref::<T>().unwrap()
}
fn get_new_value<ValueType: Any + Clone>(&self) -> &ValueType {
self.new_value.downcast_ref::<T>().unwrap()
}
}
此代码的编译失败,错误:
error: the trait `ValuesChanging` cannot be made into an object [--explain E0038]
--> <anon>:6:19
6 |> FieldChanging(Box<ValuesChanging>)
|> ^^^^^^^^^^^^^^^^^^^^
note: method `get_old_value` has generic type parameters
note: method `get_new_value` has generic type parameters
如果取消注释添加Clone
特质
error: the trait `ValuesChanging` cannot be made into an object [--explain E0038]
--> <anon>:6:23
6 |> FieldChanging(Box<ValuesChanging>)
|> ^^^^^^^^^^^^^^^^^^^^
note: the trait cannot require that `Self : Sized`
据我了解,原因是尝试在字段本身中使用trait
(作为堆栈上的未大小类型)。但是,当我把它放入Box
时,是什么原因?
它只是没有在Rust的类型系统中实现,还是有更多这些错误的根本原因? 是否有其他选项可以实现此行为?