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.