# Anotating lifetime when impenting trait

Here is the code:

``````pub trait ForeCalc {
type A;
type B;
fn calc(&self, di: &Di, data: Self::A) -> Self::B;
}

impl ForeCalc for Rank {
type A = &[f32];
type B = Vec<f32>;
fn calc(&self, _di: &Di, data: Self::A) -> Self::B {
self.rank(data)
}
}
``````

I need to annotate that the lifetime of associated type `A = &[f32]`' in `trait ForeCalc` is shorter than the lifetime of paramter `_di: &Di` from `trait ForeCalc method calc`.

The code may look like this:

``````impl<'a> ForeCalc for Rank {
type A = &'a [f32];
type B = Vec<f32>;
fn calc(&self, _di: &'a Di, data: Self::A) -> Self::B {
self.rank(data)
}
}
``````

But I do not know how to write it down. What should I do?

Use GAT (Generic Associated Types).

``````pub trait ForeCalc {
type A<'la>;
type B;
fn calc<'a>(&self, di: &'a Di, data: Self::A<'a>) -> Self::B;
}

impl ForeCalc for Rank {
type A<'la> = &'la [f32];
type B = Vec<f32>;
fn calc<'a>(&self, _di: &'a Di, data: Self::A<'a>) -> Self::B {
self.rank(data)
}
}
``````
2 Likes

There is a one more asking:

``````#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
pub struct Rank(pub usize, pub usize);
impl Rank {
pub fn rank(&self, data: &[f32]) -> Vec<f32> {
data.into_iter().map(|x| x + 1.0f32).collect()
}
}

pub trait CalcId {
fn id(&self) -> String;
}

pub trait ForeCalc {
type A<'l>;
type B;
fn calc<'l>(&self, di: &Di, data: Self::A<'l>) -> Self::B;
}

impl ForeCalc for Rank {
type A<'l> = &'l [f32];
type B = Vec<f32>;
fn calc<'l>(&self, _di: &'l Di, data: Self::A<'l>) -> Self::B {
self.rank(data)
}
}

``````

The code above fine. Then I need to implement trait `CalcId` for `Rank`, I tried do this:

``````impl<T, A, B> CalcId for T
where
T: for<'l> ForeCalc<A<'l> = A, B = B> + Debug,
{
fn id(&self) -> String {
format!("{:?}", self)
}
}
``````

This can compile, but type `Rank` has not been implemented `CalcId`. I thought this may be a matter of lifetime syntax. What should I do?

A couple things here.

1. You don't need to specify associated type if you don't use it. This works just fine.
``````impl<T> CalcId for T
where
T: ForeCalc + std::fmt::Debug,
{
fn id(&self) -> String {
format!("{:?}", self)
}
}

fn main() {
println!("{}", Rank(2, 2).id());
}
``````
1. `&[f32]` is not a single type, instead, for every different lifetime `'a`, `&'a [f32]` is a different type. So there's no type `A` satisfy `for<'l> ForeCalc<A<'l> = A>`
1 Like

So, there is no regular way I can explicitly write the lifetime, am I right?

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.