Rust:为什么泛型在不存储类型时会继承大小?

Rust: Why do generics inherit sized-ness when not storing a type?

我正在尝试在第二个结构中存储对特征的引用。该特征应该实现一个更高级别的特征,我想用它来调用专门特征上的函数。

我如何告诉 Rust 我的特征 TBox 中实现了我想调用的特征,即使它是一个组合特征?

我也试过了

impl<T: 'static> Storage<T>
where
T: DerefMut<Target=dyn ToBeCalled>,
{

然后我有 2 个 Dyn 不同的特征,我找不到施放它们的方法。它可能会导致如何在 rust 内部处理 vtables 问题。


我的程序中有以下代码(分布在一些结构和特征周围,但此代码段导致相同的编译器错误)。

use core::ops::DerefMut;

pub trait ToBeCalled {
    fn to_call(&mut self);
}
pub trait MoreAdvanced : ToBeCalled
{
    fn something_else(&mut self);
}

struct MoreAdvancedImpl
{
}

impl MoreAdvanced for MoreAdvancedImpl
{
    fn something_else(&mut self) {}
}

impl ToBeCalled for MoreAdvancedImpl
{
    fn to_call(&mut self) {}
}

pub struct Storage<T> {
    pub store: T,
}

impl<T: 'static, U> Storage<T>
where
T: DerefMut<Target=U>,
U: ToBeCalled, //Why must U be sized here?
{
    pub fn new(store: T) -> Self {
        Storage {
            store,
        }
    }
    pub fn call_high_level_function(&mut self)
    {
        self.store.to_call();
    }
}

fn main()
{
    let mai = MoreAdvancedImpl{};
    let a : Box<dyn MoreAdvanced> = Box::new(mai);
    //let a = Box::new(mai); // This works, but here the size is not "hidden" by the trait
    let _b = Storage::new(a);
}

编译输出:

error[E0277]: the size for values of type `dyn MoreAdvanced` cannot be known at compilation time
  --> src/main.rs:46:27
   |
20 |     pub fn new(store: T) -> Self {
   |     ---------------------------- required by `Storage::<T>::new`
...
46 |     let _b = Storage::new(a);
   |                           ^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn MoreAdvanced`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
默认情况下隐含

Sized。要选择退出此行为,您可以使用 ?SizedRust docs 提及:

All type parameters have an implicit bound of Sized. The special syntax ?Sized can be used to remove this bound if it's not appropriate.

Rust 书中有更多关于此的信息:

对于像我一样想要清楚说明的其他人(请参阅上面答案的评论): 变化:

impl<T: 'static, U> Storage<T>
where
T: DerefMut<Target=U>,
U: ToBeCalled, //Why must U be sized here?
{

impl<T: 'static, U: ?Sized > Storage<T>
where
T: DerefMut<Target=U>,
U: ToBeCalled, 
{