[英]Simplify Rust extension trait lifetimes when using Add trait
I need an extension trait for everything that implements AsRef<[T]>
.对于实现
AsRef<[T]>
的所有内容,我都需要一个扩展特征。 A method of this trait takes a reference to T
and based on some math with it returns a sub-slice of the original array.此特征的方法采用对
T
的引用,并基于一些数学运算返回原始数组的子切片。
Sample code can look like:示例代码如下所示:
trait Sample<T> {
fn sample(&self, element: &T, k: usize) -> &[T];
}
impl<'a, A, T> Sample<T> for A
where
A: AsRef<[T]>,
&'a T: Add<Output = T>,
T: 'a,
{
fn sample(&self, element: &T, k: usize) -> &[T] {
let array = self.as_ref();
let doubled = element + element;
&array[0..0]
}
}
It does not compile, though.但是,它不编译。
error: lifetime may not live long enough
--> src/arrays/sample.rs:15:23
|
7 | impl<'a, A, T> Sample<T> for A
| -- lifetime `'a` defined here
...
13 | fn sample(&self, element: &T, k: usize) -> &[T] {
| - let's call the lifetime of this reference `'1`
14 | let array = self.as_ref();
15 | let doubled = element + element;
| ^^^^^^^^^^^^^^^^^ requires that `'1` must outlive `'a`
I don't really understand why element
lifetime must be bigger than 'a
.我真的不明白为什么
element
生命周期必须大于'a
。
Anyways, after a while I made it work, but it does not feel right.无论如何,过了一会儿我让它工作了,但感觉不对。
use core::ops::Add;
trait KClosestExt<'t, T> {
fn find_k_closest(&'t self, element: &'t T, k: usize) -> &[T];
}
impl<'a, 't, A, T> KClosestExt<'t, T> for A
where
A: AsRef<[T]>,
&'a T: Add<Output = T>,
T: 'a + 't + PartialOrd,
't: 'a,
{
fn find_k_closest(&'t self, element: &'t T, k: usize) -> &[T] {
let array = self.as_ref();
if k > array.len() {
return array;
}
let doubled = element + element;
let left = binary_search(0, array.len() - k, |mid| doubled > &array[mid + k] + &array[mid]);
&array[left..left + k]
}
}
According to what I need, is it possible to simplify lifetime management for this example?根据我的需要,是否可以简化此示例的生命周期管理?
Your lifetime issues stem from the bound &'a T: Add<Output = T>
.您一生的问题源于绑定
&'a T: Add<Output = T>
。 This says that &T
implements Add
but only when the lifetime is exactly &'a T
.这表示
&T
实现Add
但仅当生命周期恰好&'a T
时。 What you most likely want is for<'a> &'a T: Add<Output = T>
which specifies that &T
implements Add
for any lifetime that you choose.您最可能想要的是
for<'a> &'a T: Add<Output = T>
,它指定&T
在您选择的任何生命周期内实现Add
。 (1) (1)
With this change, you sample code compiles without needing to specify any more lifetimes.通过此更改,您可以编译示例代码而无需指定更多生命周期。 playground .
游乐场。
trait Sample<T> {
fn sample(&self, element: &T, k: usize) -> &[T];
}
impl<A, T> Sample<T> for A
where
A: AsRef<[T]>,
for<'a> &'a T: std::ops::Add<Output = T>,
{
fn sample(&self, element: &T, k: usize) -> &[T] {
let array = self.as_ref();
let doubled = element + element;
&array[0..0]
}
}
(1) Strictly speaking, this is a more restrictive bound but I struggle to see a situation where the first one is fulfilled but not the second one. (1) 严格来说,这是一个更严格的界限,但我很难看到第一个满足但第二个不满足的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.