заголовок, похоже, похож на Параметр Lifetime для `Self` в сигнатуре признака , но я создаю этот новый пост, потому что я считаю, что root причина отличается.
У меня есть признак например, следуйте
trait T<'a> {
fn new(y: &'a Y) -> Self where Self: Sized;
fn do_something(&self);
}
и хотите написать обобщенную функцию c, которая принимает тип X (которая реализует черту T <'a>) и ссылку на Y, затем создайте dyn Trait T <' a>.
fn create_t_from_i<'a, I: T<'a>>(y: &'a Y) -> Box<dyn T<'a>>
моя наивная реализация похожа на это
fn create_t_from_i<'a, I: T<'a>>(y: &'a Y) -> Box<dyn T<'a>> {
return Box::new(I::new(y)) as Box<dyn T<'a>>;
}
, тогда я получил эту ошибку.
error[E0310]: the parameter type `I` may not live long enough
но тип параметра I
имеет ограничение T<'a>
, Я не понимаю, почему это не говорит о том, что rustc
to I::new(y)
жив после шага выполнения go из этой функции.
Я подозреваю, что это происходит с помощью I:new()
возвращает Self
, который не имеет аннотации к жизни. но также я не могу найти способ дать аннотацию жизни для Self.
это полный пример, чтобы вызвать ошибку.
struct Y {
z: i32
}
struct X<'a> {
y: &'a Y
}
trait T<'a> {
fn new(y: &'a Y) -> Self where Self: Sized;
fn do_something(&self);
}
impl<'a> T<'a> for X<'a> {
fn new(y: &'a Y) -> X<'a> {
return X::<'a> {
y: y
}
}
fn do_something(&self) {
println!("{}", self.y.z)
}
}
fn create_t_from_i<'a, I: T<'a>>(y: &'a Y) -> Box<dyn T<'a>> {
// error: the parameter type `I` may not live long enough
return Box::new(I::new(y)) as Box<dyn T<'a>>;
}
fn main() {
let y = Y { z: 123 };
{
let t = create_t_from_i::<X>(&y);
t.do_something()
}
}
, если я удалю определение T :: new и давая X :: new для create_t_from_i в качестве указателя на функцию, код работает (нужно использовать T + 'a вместо T <' a>). но какое существенное отличие от 1-го примера?
struct Y {
z: i32
}
struct X<'a> {
y: &'a Y
}
trait T {
fn do_something(&self);
}
impl<'a> X<'a> {
fn new(y: &'a Y) -> X<'a> {
return X::<'a> {
y: y
}
}
}
impl<'a> T for X<'a> {
fn do_something(&self) {
println!("{}", self.y.z)
}
}
fn create_t_from_i<'a, I: T + 'a>(ctor: fn (y: &'a Y) -> I, y: &'a Y) -> Box<dyn T + 'a> {
// if passing constructor function directly and using annotation I: T + 'a, rustc does not complain.
let i = ctor(y);
return Box::new(i) as Box<dyn T + 'a>;
}
fn main() {
let y = Y { z: 123 };
{
let t = create_t_from_i::<X>(X::new, &y);
t.do_something()
}
}
У кого-нибудь есть идея, почему это происходит и как сделать "ржавчину c" счастливой?
С уважением.