I have the following types (basically a vector that only returns references and a type with 2 vecors that returns a tuple of references:
struct VecValues<A> {
values: Vec<A>
}
impl<A> VecValues<A> {
fn get(&self, index: usize) -> &A {
&self.values[index]
}
}
struct ZippedValues<A,B> {
first: Vec<A>,
second: Vec<B>,
}
impl<A,B> ZippedValues<A,B> {
fn get(&self, index: usize) -> (&A,&B) {
(&self.first[index], &self.second[index])
}
}
Now I want to "unite" these in a trait (so that I can give it to other types):
trait Values {
type Item;
fn get(&self, index: usize) -> Self::Item;
}
Now I am trying to implement this types:
impl<A> Values for VecValues<A> {
type Item = &A;
fn get(&self, index: usize) -> Self::Item {
self.get(index)
}
}
impl<A,B> Values for ZippedValues<A,B> {
type Item = (&A,&B);
fn get(&self, index: usize) -> Self::Item {
self.get(index)
}
}
But that does not work:
29 | type Item = &A;
| ^ explicit lifetime name needed here
But I don't know how and where to insert the lifetime.
And I am a newbie and don't know if this approach makes sense at all :).
Thanks for your help and time!
Nathan
Miiao
2
You must tell the lifetime to compiler explicitly using generic lifetimes or 'static, so this
impl<A> Values for VecValues<A> {
type Item = &A;
fn get(&self, index: usize) -> Self::Item {
self.get(index)
}
}
turns into something like this (not tested)
impl<'a, A> Values for VecValues<A> {
type Item = &'a A;
fn get(&self, index: usize) -> Self::Item {
self.get(index)
}
}
Hallo Miiao, thanks for your reply.
If I do that I get:
28 | impl<'a, A> Values for VecValues<A> {
| ^^ unconstrained lifetime parameter
Miiao
4
Try this
Lifetime elision helps us here
But then I cannot implement ZipValues so that it returns (&A,&B)
(because it then must return a reference).
But with your tips I found a solution:
trait Values<'a> {
type Item: 'a;
fn get(&'a self, index: usize) -> Self::Item;
}
struct VecValues<A> {
values: Vec<A>
}
impl<A> VecValues<A> {
fn get(&self, index: usize) -> &A {
&self.values[index]
}
pub fn from_vec(values: Vec<A>) -> VecValues<A> {
VecValues {
values
}
}
pub fn zip_values<B>(self, second: Vec<B>) -> ZipValues<A,B> {
ZipValues::from_vecs(
self.values,
second,
)
}
}
impl<'a, A: 'a> Values<'a> for VecValues<A> {
type Item = &'a A;
fn get(&'a self, index: usize) -> Self::Item {
self.get(index)
}
}
struct ZipValues<A,B> {
first: Vec<A>,
second: Vec<B>,
}
impl<A,B> ZipValues<A,B> {
fn get(&self, index: usize) -> (&A, &B) {
(&self.first[index], &self.second[index])
}
pub fn from_vecs(first: Vec<A>, second: Vec<B>) -> ZipValues<A,B> {
ZipValues {
first,
second
}
}
}
impl<'a, A: 'a, B: 'a> Values<'a> for ZipValues<A, B> {
type Item = (&'a A, &'a B);
fn get(&'a self, index: usize) -> Self::Item {
self.get(index)
}
}
1 Like
Miiao
6
Oh, I finally understood what you meant. Seems like it’s too late so I’m just proud of you. Good luck
1 Like
Thanks for your time and expertise!
1 Like
system
Closed
8
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.