问题
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!
回答1:
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 }
}
}
来源:https://stackoverflow.com/questions/24853111/sorting-out-different-lifetimes-on-self-and-a-method