保存任何类型的值

时间:2016-08-14 18:31:44

标签: rust

我尝试在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的类型系统中实现,还是有更多这些错误的根本原因? 是否有其他选项可以实现此行为?

0 个答案:

没有答案