gpt4 book ai didi

rust - 如何注释返回 Self 的特征实现,已指定生命周期?

转载 作者:行者123 更新时间:2023-12-03 11:43:16 26 4
gpt4 key购买 nike

标题似乎与 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<'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> ,我不明白为什么这不告诉 rustcI::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<'a>)。但与第一个例子有什么本质区别?
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”开心吗?

问候。

最佳答案

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 'static + T<'a>> 

这反过来意味着 I还必须具有静态生命周期才能将其存储在返回的框中(即您需要 I: 'static 绑定(bind))。

为了解决这个问题,您可以为 I 的生命周期添加另一个生命周期参数。 ,并在返回的盒装特征中使用它。无论 I 的生命周期如何,这都会起作用实际上是:

fn create_t_from_i<'a, 'b, I: 'b + T<'a>>(y: &'a Y) -> Box<dyn 'b + T<'a>> 
// ^^^^^^^^^ ^^^^

Playground example

关于rust - 如何注释返回 Self 的特征实现,已指定生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61400514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com