让我们从你问这个问题的方式开始,希望你将来能够提出更好的问题。您得到的完整错误是:
<anon>:27:37: 27:52 error: the type of this value must be known in this context
<anon>:27 changes.iter().map(|e| newAgg.Apply(e));
^~~~~~~~~~~~~~~
请注意,编译器错误消息显示您确切的哪一位代码出错。提问时包含该错误很有用。
你还包括了无关的细节。例如,GetUncomittedChanges
,id
和GetId
在您的示例中都未使用。解决问题时,应该生成一个MCVE。这有助于您更好地理解问题,并帮助人们帮助您查看更少的代码,从而加快周转速度。
你的代码中有许多问题,但让我们开始在第一个错误:
let newAgg = AggregateRoot::new2();
这是说“对任何可能的AggregateRoot
,创建一个新的”。许多具体类型可以实现特征(这是特征点),但编译器需要知道给定实例需要分配多少空间。可能有一个结构需要1个字节或200个字节; 这个大小写需要多少空间分配?
要取得进展,您可以改用Self::new2
。这意味着要创建当前实现者的新实例。
下一个错误是
<anon>:20:16: 20:40 error: no method named `MarkChangesAsCommitted` found for type `Self` in the current scope
<anon>:20 newAgg.MarkChangesAsCommitted();
^~~~~~~~~~~~~~~~~~~~~~~~
您正在呼吁从性状实施一个具体类型的方法;这根本没有任何意义。如果bool
实现了这个特性会发生什么?它没有MarkChangesAsCommitted
方法。在这种情况下,我不知道你想要什么,所以我只是删除它。
现在你得到这个错误:
<anon>:19:9: 19:16 error: `changes` does not live long enough
<anon>:19 changes.iter().map(|e| newAgg.Apply(e));
^~~~~~~
note: reference must be valid for the static lifetime...
<anon>:17:5: 21:6 note: ...but borrowed value is only valid for the scope of parameters for function at 17:4
那是因为你的方法Apply
希望给予实现Any
一个类型。但是,您通过了&Box<Any>
。Any
的使用期限为'static
,并且该引用不是静态的。一个直接的变化是接受对实现Any
类型的引用:
fn Apply<U: Any>(&self, arg: &U);
既然代码编译,还有一些风格问题进行修复:
- 没有空间之前
:
- 没有空间后
>
- 之前没有空间
(
- 内
()
map
没有空间不应该被用于副作用
- 函数和变量名
camel_case
- 大部分时间里,接受的
&[T]
而不是Vec<T>
作为函数参数。
- 使用“埃及”括号,除非您使用
where
条款。
总之,代码如下:
use std::any::Any;
struct Aggregate<T: AggregateRoot> {
agg: T,
changes: Vec<Box<Any>>
}
impl<T: AggregateRoot> Aggregate<T> {
fn mark_changes_as_committed(&self) { }
}
trait AggregateRoot {
fn new() -> Self;
fn load_from_history(changes: &[Box<Any>]) -> Self
where Self: Sized
{
let new_agg = Self::new();
for change in changes { new_agg.apply(change) }
new_agg
}
fn apply<U: Any>(&self, arg: &U);
}
fn main() {}
Is there a way to constrain the concrete types of the AggregateRoot
to Aggregates
so mark_changes
can be called?
不,我知道的。这听起来像你想移动到mark_changes
性状,并迫使性状的所有实现实现它:
trait AggregateRoot {
fn load_from_history(changes: &[Box<Any>]) -> Self
where Self: Sized
{
let new_agg = Self::new();
for change in changes { new_agg.apply(change) }
new_agg.mark_changes_as_committed();
new_agg
}
fn mark_changes_as_committed(&self);
// ...
}
的代码提交有问题,并按照上述方法没有错误。相反,在进行代码编译之后,我得到的错误是“特征'core :: marker :: Sized'没有针对”Self“类型和”没有名为'map'的类型“实现。请创建一个[MCVE](/ help/mcve),最好在[Rust Playground]上编译(https://play.rust-lang.org/)。 – Shepmaster
Where子句让你发现错误,但看起来不正确,第二个错误是用iter()修复的。第一个错误是你如何做到这一点..我不知道该怎么做才能编译。这是我目前的尝试 – user1496062