假设有一个允许附加对象引用的简单特征.我在这里使用了String
,以使代码稍微简单一些.
trait Attachable<'a> {
fn new() -> Self;
fn attach(&mut self, value: &'a String);
}
简单化的实现可能如下所示:
struct SomeAttachable<'a> {
id: Option<&'a String>,
}
impl<'a> Attachable<'a> for SomeAttachable<'a> {
fn new() -> Self {
Self { id: None }
}
fn attach(&mut self, value: &'a String) {
self.id = Some(value)
}
}
而且使用它可以开箱即用.
let mut object = SomeAttachable::new();
let value = "hello".to_string();
object.attach(&value);
但是,当将其放入仅提供可附加类型的泛型函数中时,它会中断.
fn do_stuff<'a, T: Attachable<'a>>() {
let mut object = T::new();
let value: String = "hello".to_string();
object.attach(&value); // breaks here since value does not live long enough
}
我假设在调用函数do_stuff
时检测到生存期,然后value
具有"错误的"生存期要求.我如何纠正实现do_stuff
中的生命周期问题.
调整函数签名以:
fn do_stuff_with_argument<'a, T: Attachable<'a>>(value: &'a String) {
let mut bla = T::new();
bla.attach(&value);
}
将解决问题,因为现在再次正确检测到生存期,因为它是输入引用参数的一部分.但这对我来说不是一个合适的解决方案.do_stuff
函数应处理函数内部的所有逻辑,而不需要任何函数参数.只允许泛型参数,如生存期和类型.
我假设我可能不得不使用更高等级的特征界限并实现do_stuff
个如下所示:
fn do_stuff<T>()
where
T: for<'a> Attachable<'a>,
{
let mut object = T::new();
let value: String = "hello".to_string();
object.attach(&value);
}
但这导致Rust抱怨说,Attachable
的实现对于SomeAttachable
来说还不够通用.
为了提供一些上下文:我在基于generic-test
箱的单元测试中需要这样做,其中验证了特征的行为.