用寿命参数动态建立结构
试图从Rust中的另一棵树结构中构建树结构 - 建造的树结构取决于终生参数。
下面的特征代表了我的搜索树结构的简化版本(我希望是动态构建的):
trait SPart {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubSPart<PP: SPart> {
fn promote_search<'b>(&'b self, parent: &'b PP, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
struct SP<'a>(pub Vec<Box<dyn SubSPart<Self> + 'a>>);
struct SSP(pub i32);
impl<'a> SPart for SP<'a> {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>) {
for c in &self.0 {
c.promote_search(self, queue);
}
}
}
impl<'a> SubSPart<SP<'a>> for SSP {
fn promote_search<'b>(&'b self, parent: &'b SP, queue: &mut Vec<Box<dyn SPart + 'b>>) {
queue.push(Box::new(SP(vec![])));
}
}
零件和子部分可以包含对数据的参考,因此我认为寿命参数是必要的。 这些部分通常在递归函数中也短暂,可以动态地引用递归调用中早期帧的数据。
这一切都与颜色一起使用,所以现在我有兴趣通过单独的树结构动态构建此初始树结构:
trait BPart {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubBPart<P, PP: SPart> {
fn build<'b>(&'b self, parent: &'b P, v: &mut Vec<Box<dyn SubSPart<PP> + 'b>>);
}
struct BP<'a>(pub Vec<Box<dyn SubBPart<Self, SP<'a>>>>, pub i32);
struct SBP(pub i32);
impl<'a> BPart for BP<'a> {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>) {
let mut sv = vec![];
for sp in &self.0 {
sp.build(self, &mut sv);
}
let sp = SP(sv);
v.push(Box::new(sp));
}
}
impl<'a> SubBPart<BP<'a>, SP<'a>> for SBP {
fn build<'b>(&'b self, parent: &'b BP<'a>, v: &mut Vec<Box<dyn SubSPart<SP> + 'b>>) {
v.push(Box::new(SSP(self.0 + parent.1)));
}
}
fn main() {
let bp = BP(vec![Box::new(SBP(42))], 21);
let mut v = vec![];
bp.build(&mut v);
}
但是,这似乎是:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
看起来寿命与bpart('a)< /code>在创建
Spart
和subpart
时,但我不知道如何在生锈中表达这一点。
a href =“ https://play.rust-lang.org/?version=stable&; mode = debug&;
< 强>编辑: 添加了特质方法和示例以及主要方法。
Trying to build a tree structure from another tree structure in Rust - where the the built tree structure are dependent on lifetimes parameters.
The traits below represents a simplified version of my search tree structure (the one I wish for to be build dynamically):
trait SPart {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubSPart<PP: SPart> {
fn promote_search<'b>(&'b self, parent: &'b PP, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
struct SP<'a>(pub Vec<Box<dyn SubSPart<Self> + 'a>>);
struct SSP(pub i32);
impl<'a> SPart for SP<'a> {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>) {
for c in &self.0 {
c.promote_search(self, queue);
}
}
}
impl<'a> SubSPart<SP<'a>> for SSP {
fn promote_search<'b>(&'b self, parent: &'b SP, queue: &mut Vec<Box<dyn SPart + 'b>>) {
queue.push(Box::new(SP(vec![])));
}
}
The parts and subparts can contain references to data, hence I think the lifetime-parameter is necessary.
These parts are usually also short-lived in a recursive function, and can be created dynamically referring back to data from earlier frames in the recursive call.
This all works with flying colors, so now I'm interested in building this initial tree structure dynamically from a separate tree structure:
trait BPart {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubBPart<P, PP: SPart> {
fn build<'b>(&'b self, parent: &'b P, v: &mut Vec<Box<dyn SubSPart<PP> + 'b>>);
}
struct BP<'a>(pub Vec<Box<dyn SubBPart<Self, SP<'a>>>>, pub i32);
struct SBP(pub i32);
impl<'a> BPart for BP<'a> {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>) {
let mut sv = vec![];
for sp in &self.0 {
sp.build(self, &mut sv);
}
let sp = SP(sv);
v.push(Box::new(sp));
}
}
impl<'a> SubBPart<BP<'a>, SP<'a>> for SBP {
fn build<'b>(&'b self, parent: &'b BP<'a>, v: &mut Vec<Box<dyn SubSPart<SP> + 'b>>) {
v.push(Box::new(SSP(self.0 + parent.1)));
}
}
fn main() {
let bp = BP(vec![Box::new(SBP(42))], 21);
let mut v = vec![];
bp.build(&mut v);
}
However, this fails with:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
It seems like the lifetime is tied to the BPart ('a)
where I wish for the lifetime to be valid for any lifetime ('b)
at the time of creation of the SPart
and SubSPart
, but I'm unaware of how to express this in Rust.
Edit:
Added trait methods and examples, and main method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是终生约束的意大利面条,因此我将尝试分解局限性:
Lifetime
'B
由于其在&amp; mut Vec&lt box&lt; box&lt;中而不变。 Dyn Spart +'B&gt;
。大多数终身注释都是协变量的,这意味着可以根据需要缩短其与其他约束。但是编译器不能在这里这样做,因为如果缩短,该值可以变异或分配到比其所需的短的值。Lifetime
'a
由于其在vec&lt; box&lt; dyn subbpart&lt; self,sp&lt;'a&gt;&gt;&gt;&gt;&gt;
而不变。特质&lt;'a&gt;
的实施者可以使用内部的突变性,因此,出于上述相同的原因,不能是协变量的。'a:'b
- 使用&amp;'b self
暗示bp&lt;'a&gt;:'b
,因此意味着'a:'b
意味着'b
的寿命不能超过'a
的寿命。'b:'a
- 使用dyn subpart&lt; pp&gt; +'b
通常意味着特征对象可以从'b
借用,但是因为pp
是sp&lt;'a&gt;
还允许它从'a
借用。这意味着为了'B
从subbpart ::构建
与bpart :: build
对齐,然后'a
'a < /code>不能超越
'b
。要满足上述约束,必须是
'a =='b
。但是'b
是特征函数签名作为通用参数的一部分,因此必须允许它是任何东西。我对您如何修复它没有很好的建议,因为您的代码对这些生命和特质抽象的目的非常困惑。
This is quite the spaghetti of lifetime constraints so I'll try to break down the limitations:
The lifetime
'b
is invariant due to its use in&mut Vec<Box<dyn SPart + 'b>>
. Most lifetime annotations are covariant, meaning it can be shortened as necessary to align with other constraints. But the compiler cannot do so here because, if shortened, the value could be mutated or assigned to a value that lives shorter than it needs to.The lifetime
'a
is invariant due to its use inVec<Box<dyn SubBPart<Self, SP<'a>>>>
. An implementor ofTrait<'a>
can use inner mutability and thus, for the same reasons above, cannot be covariant.'a: 'b
- The use of&'b self
impliesBP<'a>: 'b
and thus implies'a: 'b
meaning that the lifetime of'b
cannot outlive the life of'a
.'b: 'a
- The use ofdyn SubSPart<PP> + 'b
normally means that the trait object is allowed to borrow from'b
but becausePP
isSP<'a>
it is also allowed to borrow from'a
. This means that in order for'b
fromSubBPart::build
to line up withBPart::build
, then'a
cannot outlive'b
.To satisfy the above constraints, it must be that
'a == 'b
. But'b
is part of a trait's function signature as a generic parameter, so it must be allowed to be anything.I don't have a good recommendation for you for how to fix it since your code is very obfuscated as to what these lifetimes and trait abstractions are for.
确实需要更高的寿命。而不是锁定特定的生命周期,而是将
'a
作为structbp
中的通用参数,可以指定较高友善的寿命如下:答案:在我的情况下,
Spart
或subpart
可以包含来自其构建器bpart
bpart 或subbpart
的数据引用。这需要改变特征:然后对IMPS进行相应调整。
This is indeed a case where a higher kinded lifetime is needed. Instead of locking in on a specific lifetime, giving
'a
as a generic parameter in the structBP
, the use of a higher kinded lifetime can be specified as follows:To complete the answer: In my case, a
SPart
orSubSPart
can contain references to data from its builderBPart
orSubBPart
. This required changes to the traits:and then adjusting the impls accordingly.