I am trying to establish common trait on top of NDArray and SPRS (sparse array) so my library can be called with both of them.
The goal is to have unified API for 2D array, from which we can extract views to rows (samples) and do many other things like dot products, ...
I hit the wall with lifetime on traits right now for view extraction, simplified example below:
use ndarray::{ArrayView1, Axis, Array2};
pub trait Sample<'a> {
fn s(&self) -> usize;
}
impl<'a> Sample<'a> for ArrayView1<'a, f64> {
fn s(&self) -> usize {
self.len()
}
}
pub trait WithRows<'a> {
type Row: Sample<'a>;
fn row(&'a self, r: usize) -> Self::Row;
}
impl<'a> WithRows<'a> for Array2<f64> {
type Row = ArrayView1<'a, f64>;
fn row(&'a self, r: usize) -> ArrayView1<'a, f64> {
self.subview(Axis(0), r)
}
}
fn a<'a, T: WithRows<'a>>(x: &'a T) {
let r = x.row(0);
r.s();
}
fn b<'a, T: WithRows<'a> + 'a>(x: T) {
let r = x.row(0);
r.s();
}
Function a compiles without problem.
Function b produces:
rror[E0597]: `x` does not live long enough
--> src/data_types.rs:35:13
|
35 | let r = x.row(0);
| ^ does not live long enough
36 | r.s();
37 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 34:1...
--> src/data_types.rs:34:1
|
34 | / fn b<'a, T: WithRows<'a> + 'a>(x: T) {
35 | | let r = x.row(0);
36 | | r.s();
37 | | }
| |_^
I tried several approaches with using lifetime subtyping, but none of them seem to work.