为什么终身省略对特征不起作用
Why doesn't lifetime elision work for traits
我想创建我自己的特征,它应该基于 f32
的索引产生 i32
。我尝试了以下方法,似乎确实有效:
use std::ops::Index;
// trait by value
pub trait MyTrait:
Index<f32, Output=i32> {
}
虽然按值传递 f32
可能是个好主意,但对于更复杂的类型,我宁愿传递对值的引用,所以我尝试了以下操作:
// trait by reference, not compiling
pub trait MyTrait:
Index<&f32, Output=i32> {
}
包括这个定义给了我一个 error[E0106]: missing lifetime specifier
。我得到了这个变体:
// trait by reference, compiling
pub trait MyTrait<'a>:
Index<&'a f32, Output=i32> {
}
问题是:虽然这种方法有效,但它意味着任何实现 MyTrait
的类型都需要一个明确的生命周期参数。
然而,这似乎是不必要的:如果我为自己的结构实现 Index
特性,我就不需要任何生命周期:
struct Test {
value: i32
}
impl Index<&f32> for Test {
type Output = i32;
fn index(&self, _key: &f32) -> &Self::Output {
&self.value
}
}
问题一:为什么在trait的定义中需要额外的lifetime,为什么不能省略?
问题 2:我可以通过避免引入生命周期的方式来定义特征吗?
Why do I need the additional lifetime in the definition of the trait, why can't it be elided?
Lifetime elision仅适用于函数签名。所以不,它不适用于您的特征定义。
Can I define the trait in such a way as to avoid having to introduce the lifetime?
当然,您可以像 std::ops::Index
那样使用泛型参数:
use std::ops::Index;
pub trait MyTrait<T>: Index<T, Output = i32> {}
struct Test {
value: i32,
}
impl Index<&f32> for Test {
type Output = i32;
fn index(&self, _key: &f32) -> &Self::Output {
&self.value
}
}
impl MyTrait<&f32> for Test {}
据我所知(我不是 100% 确定,文档对此相当沉默),这个:
impl Index<&f32> for Test { /* ... */ }
是shorthand为此:
impl <'a> Index<&'a f32> for Test { /* ... */ }
换句话说,你实现了 any 生命周期的特性。
类似地,您可以要求在您的绑定中的任何生命周期内实现该特征:
pub trait MyTrait:
for<'a> Index<&'a f32, Output = i32> {
// ...
}
我想创建我自己的特征,它应该基于 f32
的索引产生 i32
。我尝试了以下方法,似乎确实有效:
use std::ops::Index;
// trait by value
pub trait MyTrait:
Index<f32, Output=i32> {
}
虽然按值传递 f32
可能是个好主意,但对于更复杂的类型,我宁愿传递对值的引用,所以我尝试了以下操作:
// trait by reference, not compiling
pub trait MyTrait:
Index<&f32, Output=i32> {
}
包括这个定义给了我一个 error[E0106]: missing lifetime specifier
。我得到了这个变体:
// trait by reference, compiling
pub trait MyTrait<'a>:
Index<&'a f32, Output=i32> {
}
问题是:虽然这种方法有效,但它意味着任何实现 MyTrait
的类型都需要一个明确的生命周期参数。
然而,这似乎是不必要的:如果我为自己的结构实现 Index
特性,我就不需要任何生命周期:
struct Test {
value: i32
}
impl Index<&f32> for Test {
type Output = i32;
fn index(&self, _key: &f32) -> &Self::Output {
&self.value
}
}
问题一:为什么在trait的定义中需要额外的lifetime,为什么不能省略?
问题 2:我可以通过避免引入生命周期的方式来定义特征吗?
Why do I need the additional lifetime in the definition of the trait, why can't it be elided?
Lifetime elision仅适用于函数签名。所以不,它不适用于您的特征定义。
Can I define the trait in such a way as to avoid having to introduce the lifetime?
当然,您可以像 std::ops::Index
那样使用泛型参数:
use std::ops::Index;
pub trait MyTrait<T>: Index<T, Output = i32> {}
struct Test {
value: i32,
}
impl Index<&f32> for Test {
type Output = i32;
fn index(&self, _key: &f32) -> &Self::Output {
&self.value
}
}
impl MyTrait<&f32> for Test {}
据我所知(我不是 100% 确定,文档对此相当沉默),这个:
impl Index<&f32> for Test { /* ... */ }
是shorthand为此:
impl <'a> Index<&'a f32> for Test { /* ... */ }
换句话说,你实现了 any 生命周期的特性。
类似地,您可以要求在您的绑定中的任何生命周期内实现该特征:
pub trait MyTrait:
for<'a> Index<&'a f32, Output = i32> {
// ...
}