【发布时间】:2022-12-02 22:43:10
【问题描述】:
错误:
所以我收到以下错误:
error[E0277]: the size for values of type 'dyn Getter' cannot be known at compilation time
struct PlusFive;
impl Operator for PlusFive {
fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a> {
Box::new(MapGetter {
source: a, // A pointer to some Getter
f: |n:i32| n + 5 // A way to later compute +5 on source
});
}
}
- 特征
Sized没有为dyn Getter实现 - 为
MapGetter<T, F>实现了特征Getter
问题:
我不确定这个错误是什么意思或如何解决它。 dyn Getter 的大小无法知道,但 MapGetter 的大小肯定可以!并且由于 MapGetter 是实现 Getter 特性的具体类型,所以我不明白为什么我不能将其装箱并返回。
我在这里遗漏了一些东西。我能够把MapGetter 装箱,我不能做的就是将它提升为特征对象?
如果有助于在上下文中查看所有内容,这是我正在使用的完整示例:
笔记:
总的来说,我一直在尝试通过动态调度来做到这一点。部分是因为我想看看可以做什么,部分是因为我预见到自己想要一个 dyn Operators 的列表,其中下面的具体类型可能会有所不同。
我不想直接将运算符附加到 Getter 特征,因为最终我希望运算符代表可重用的逻辑片段,因此它们可以在事后(或不止一次)应用于 Getter
完整上下文:
trait Getter {
fn compute(&self) -> i32;
fn pipe(&self, operator: &dyn Operator) -> Box<dyn Getter>
where
Self: Sized,
{
operator.apply(&self)
}
}
impl<T: Getter> Getter for &T {
fn compute(&self) -> i32 {
(*self).compute()
}
}
impl<T: Getter> Getter for Box<T> {
fn compute(&self) -> i32 {
(*self).compute()
}
}
struct PureGetter<T>(T);
impl Getter for PureGetter<i32> {
fn compute(&self) -> i32 {
self.0
}
}
struct MapGetter<T, F> {
source: T,
(*self).compute()
f: F,
}
impl<T, F> Getter for MapGetter<T, F>
where
T: Getter,
F: FnMut(i32) -> i32 + Clone,
{
fn compute(&self) -> i32 {
(self.f.clone())(self.source.compute())
}
}
trait Operator {
fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a>;
}
struct PlusFive;
impl Operator for PlusFive {
fn apply<'a>(&self, a: &'a dyn Getter) -> Box<dyn Getter + 'a> {
Box::new(MapGetter {
source: a,
f: |n:i32| n + 5
})
}
}
fn main() {
let result = PureGetter(0).pipe(&PlusFive).compute();
println!("{:#?}", result);
}
error[E0277]: the size for values of type `dyn Getter` cannot be known at compilation time
--> src/main.rs:71:9
|
71 | / Box::new(MapGetter {
72 | | source: a,
73 | | f: |n:i32| n + 5
74 | | })
| |__________^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Getter`
= help: the trait `Getter` is implemented for `MapGetter<T, F>`
note: required for `&dyn Getter` to implement `Getter`
--> src/main.rs:24:17
|
24 | impl<T: Getter> Getter for &T {
| ^^^^^^ ^^
= note: 1 redundant requirement hidden
= note: required for `MapGetter<&dyn Getter, [closure@src/main.rs:73:16: 73:23]>` to implement `Getter`
= note: required for the cast from `MapGetter<&dyn Getter, [closure@src/main.rs:73:16: 73:23]>` to the object type `dyn Getter`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `messin` due to previous error
【问题讨论】:
-
为什么不在结构上而不是在实现上添加特征边界。你会得到更清晰的错误
-
您能否添加
cargo check提供的完整错误?我试图在操场上查看您的代码,但解决眼前的问题会导致出现几个新问题。所以我不确定这是否与您看到的相同。 -
@Cerberus 当然,我已经用完整的错误更新了问题
标签: rust