Rust:为什么泛型在不存储类型时会继承大小?
Rust: Why do generics inherit sized-ness when not storing a type?
我正在尝试在第二个结构中存储对特征的引用。该特征应该实现一个更高级别的特征,我想用它来调用专门特征上的函数。
我如何告诉 Rust 我的特征 T
在 Box
中实现了我想调用的特征,即使它是一个组合特征?
我也试过了
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
。要选择退出此行为,您可以使用 ?Sized
。 Rust 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,
{
我正在尝试在第二个结构中存储对特征的引用。该特征应该实现一个更高级别的特征,我想用它来调用专门特征上的函数。
我如何告诉 Rust 我的特征 T
在 Box
中实现了我想调用的特征,即使它是一个组合特征?
我也试过了
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
。要选择退出此行为,您可以使用 ?Sized
。 Rust 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,
{