假设一个简单的trait允许附加一个对象引用,我在这里使用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
crate的单元测试,在那里验证trait的行为。
1条答案
按热度按时间ycl3bljg1#
你可以使用
AttachableTag
trait,它有一个泛型关联类型,可以为任何'a
提供一个Attachable<'a>
(你也可以使用相同的trait和类型,但我更喜欢这样):但是,这会产生错误:
要修复此问题,请将
value
的声明移到object
之前: