【发布时间】:2026-02-15 10:20:02
【问题描述】:
标题似乎与 Lifetime parameter for `Self` in trait signature 相似,但我创建了这个新帖子,因为我认为根本原因不同。
我有一个像下面这样的特质
trait T<'a> {
fn new(y: &'a Y) -> Self where Self: Sized;
fn do_something(&self);
}
并想编写接受类型 X(实现 trait T)和 Y 引用的泛型函数,然后创建 dyn Trait T。
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 到I::new(y) 在执行步骤从这个函数出去之后是活动的。
我怀疑这是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)。但是与第一个示例有什么本质区别?
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()
}
}
有人知道为什么会发生这种情况以及如何让“rustc”开心吗?
问候。
【问题讨论】:
标签: rust