问题描述
我发布了类似的问题(铁锈寿命错误预期混凝土寿命,但昨晚找到了约束寿命),但现在仍不知道如何将其应用于这种情况.再次,下面是一个简化的示例:
struct Ref;
struct Container<'a> {
r : &'a Ref
}
struct ContainerB<'a> {
c : Container<'a>
}
trait ToC {
fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> Self;
}
impl<'b> ToC for ContainerB<'b> {
fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
ContainerB{c:c}
}
}
出现错误消息:
test.rs:16:3: 18:4 error: method `from_c` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter 'a
test.rs:16 fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17 ContainerB{c:c}
test.rs:18 }
test.rs:16:67: 18:4 note: expected concrete lifetime is the lifetime 'b as defined on the block at 16:66
test.rs:16 fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17 ContainerB{c:c}
test.rs:18 }
error: aborting due to previous error
我认为需要发生的是,我需要某种方式来等同于/子类型寿命'a
和寿命'b
.与前面的示例不同,没有&self
可以使用.我想我可以通过向我的trait(trait ToC<'a> ...
)添加一个生命周期类型参数来做到这一点,但是我不希望这样做,因为它在我想将trait用作类型绑定的任何地方都添加了额外的<'a>
. /p>
如果有人好奇(AKA可以忽略这一点),我可能会在库中使用它在rust和python类型之间进行转换.特质是此处.一切正常,但是我正在尝试围绕PyObject
类型(例如numpy ndarray)实现包装,并能够以此与PyObject进行相互转换.
再次感谢!
这归结为与您上一个问题大致相同的问题.
Self
是指您要为其实现特征的类型.在这种情况下,它是ContainerB<'b>
,因此,关于它的全部不同之处适用.这次,这一次也没有将'b
和'a
绑定在一起的情况;生存期是并且必须由编译器假定是可能不相交的. (这与保证'b ≥ 'a
的&'a ContainerB<'b>
不同.)
一旦使用了在方法上定义的生存期,就不可能在Self
上绑定生存期.最好的解决方案是将生命周期参数从方法转移到特征上:
trait ToC<'a> {
fn from_c(r: &'a Ref, c: Container<'a>) -> Self;
}
impl<'a> ToC<'a> for ContainerB<'a> {
fn from_c(r: &'a Ref, c: Container<'a>) -> ContainerB<'a> {
ContainerB { c: c }
}
}
I posted a similar question (Rust lifetime error expected concrete lifetime but found bound lifetime) last night, but still can't figure out how to apply it to this case now. Once again, a simplified example bellow:
struct Ref;
struct Container<'a> {
r : &'a Ref
}
struct ContainerB<'a> {
c : Container<'a>
}
trait ToC {
fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> Self;
}
impl<'b> ToC for ContainerB<'b> {
fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
ContainerB{c:c}
}
}
With the error message:
test.rs:16:3: 18:4 error: method `from_c` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter 'a
test.rs:16 fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17 ContainerB{c:c}
test.rs:18 }
test.rs:16:67: 18:4 note: expected concrete lifetime is the lifetime 'b as defined on the block at 16:66
test.rs:16 fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17 ContainerB{c:c}
test.rs:18 }
error: aborting due to previous error
What I think needs to happen is I need some way to equate / sub-type lifetime 'a
, and lifetime 'b
. Unlike the previous example there is no &self
to use. I am guessing I can do this by adding a lifetime type argument to my trait(trait ToC<'a> ...
), but I would prefer not to do this as it adds extra <'a>
everywhere I want to use the trait as a type bound.
If anybody is curious(AKA can ignore this) where this might actually come up, I am using it in a library to convert between rust and python types. The trait is here. Everything works fine, but I am trying to implement a wrapper around the PyObject
type (such as a numpy ndarray) and be able to convert it to and from a PyObject with this.
Thanks again!
This boils down to much the same problem as in your previous question.
Self
refers to the type you are implementing the trait for. In this case it is ContainerB<'b>
, and so the whole thing about its not being the same applies; this time this time there is nothing to tie 'b
and 'a
together, either; the lifetimes are and must be assumed by the compiler to be potentially disjoint. (This is as distinct to the &'a ContainerB<'b>
which guaranteed 'b ≥ 'a
.)
Once you are using a lifetime defined on the method, tying that in with a lifetime on Self
is not possible. The solution that is probably best is to shift the lifetime parameter from the method onto the trait:
trait ToC<'a> {
fn from_c(r: &'a Ref, c: Container<'a>) -> Self;
}
impl<'a> ToC<'a> for ContainerB<'a> {
fn from_c(r: &'a Ref, c: Container<'a>) -> ContainerB<'a> {
ContainerB { c: c }
}
}
这篇关于在Self上分类不同的生存期和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!