Этот оригинальный дизайн невозможен.Index
ожидает, что метод index
вернет ссылку на значение типа Self::Output
:
fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
Я увеличил время жизни выше, чтобы подчеркнуть, что возвращаемое значение должен прожить столько, сколько self
сам .Это достижимо, когда указанное значение содержится в вызываемом объекте, но это не относится к переносимому значению.В одной из ваших попыток:
fn index<'a>(&'a self, range: ops::Range<usize>) -> &'a Self::Output {
&Wrap::<&[i8]>::new(&self.0[range])
}
Это создает ссылку на Wrap
объект, который живет только локально (и поэтому не переживает 'a
).В этом случае потребовалась бы другая черта, такая как WrapIndex
, которая, к сожалению, не содержала бы тот же синтаксический сахар.Он также не может быть обобщен без общих ассоциированных типов (GAT).
pub trait WrapIndex<Idx> where
Idx: ?Sized, {
type Output: ?Sized;
fn wrap_index(&self, index: Idx) -> Wrap<&Self::Output>;
}
Если вы не возражаете, выставив все методы из типа среза в Wrap
, вы также можете реализовать Deref
для этой обертки, получая таким образом индексацию и нарезку бесплатно.
impl<T> Deref for Wrap<T>
where T: Deref
{
type Target = <T as Deref>::Target;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}