简体   繁体   中英

Define a subtrait of Index defined on a reference

I want to define a trait that's a subtrait of std::ops::Index for a concrete reference type, eg something like this:

trait RefIndex<'a>: Index<&'a usize> {}

Which I can do, however, when I try to use it like:

fn get_sum<'a>(inp: impl RefIndex<'a, Output = u64>) -> u64 {
    let mut sum = 0;
    for i in 0..1 {
        sum += inp[&i];
    }
    sum
}

I get

5 | fn get_sum<'a>(inp: impl RefIndex<'a, Output = u64>) -> u64 {
  |            -- lifetime `'a` defined here
...
8 |         sum += inp[&i];
  |                    ^^
  |                    |
  |                    borrowed value does not live long enough
  |                    requires that `i` is borrowed for `'a`
9 |     }
  |     - `i` dropped here while still borrowed

I think this indicates that rust thinks the implementation of Index is only valid for references that live as long as get_sum when really I only want it for the transient lifetime of the function call. However, I'm not sure how to annotate RefIndex (or get_sum ) in such a way to define that as the appropriate lifetime.

Note, for concrete types this problem doesn't happen, rust is able to infer the reduced lifetime of the reference and the following compiles just fine:

struct MyVec<T>(Vec<T>);

impl<T> Index<&usize> for MyVec<T> {
    type Output = T;

    fn index(&self, ind: &usize) -> &T {
        &self.0[*ind]
    }
}

fn get_sum_vec(inp: MyVec<u64>) -> u64 {
    let mut sum = 0;
    for i in 0..1 {
        sum += inp[&i];
    }
    sum
}

Filipe Rodrigues answered it above:

RefIndex needs an explicit lifetime parameter, but declaring it as part of function scope unnecessarily bound it too broadly. By using the for<> syntax it can be bound more narrowly, which works.

fn get_sum(inp: impl for<'a> RefIndex<'a, Output = u64>) -> u64 {
    let mut sum = 0;
    for i in 0..1 {
        sum += inp[&i];
    }
    sum
}

I was not aware of the for syntax before now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM