参数类型可能寿命不够长?

2024-04-20

以下代码段给我一个错误:

use std::rc::Rc;

// Definition of Cat, Dog, and Animal (see the last code block)
// ...

type RcAnimal = Rc<Box<Animal>>;
fn new_rc_animal<T>(animal: T) -> RcAnimal
where
    T: Animal /* + 'static */ // works fine if uncommented
{
    Rc::new(Box::new(animal) as Box<Animal>)
}

fn main() {
    let dog: RcAnimal = new_rc_animal(Dog);
    let cat: RcAnimal = new_rc_animal(Cat);
    let mut v: Vec<RcAnimal> = Vec::new();
    v.push(cat.clone());
    v.push(dog.clone());
    for animal in v.iter() {
        println!("{}", (**animal).make_sound());
    }
}
error[E0310]: the parameter type `T` may not live long enough
 --> src/main.rs:8:13
  |
4 | fn new_rc_animal<T>(animal: T) -> RcAnimal
  |                  - help: consider adding an explicit lifetime bound `T: 'static`...
...
8 |     Rc::new(Box::new(animal) as Box<Animal>)
  |             ^^^^^^^^^^^^^^^^
  |
note: ...so that the type `T` will meet its required lifetime bounds
 --> src/main.rs:8:13
  |
8 |     Rc::new(Box::new(animal) as Box<Animal>)
  |             ^^^^^^^^^^^^^^^^

但这编译得很好:

use std::rc::Rc;

// Definition of Cat, Dog, and Animal (see the last code block)
// ...

fn new_rc_animal<T>(animal: T) -> Rc<Box<T>>
where
    T: Animal,
{
    Rc::new(Box::new(animal))
}

fn main() {
    let dog = new_rc_animal(Dog);
    let cat = new_rc_animal(Cat);
}

错误的原因是什么?唯一真正的区别似乎是运算符的使用as。怎样才能一个type活得不够长? ()

// Definition of Cat, Dog, and Animal
trait Animal {
    fn make_sound(&self) -> String;
}

struct Cat;
impl Animal for Cat {
    fn make_sound(&self) -> String {
        "meow".to_string()
    }
}

struct Dog;
impl Animal for Dog {
    fn make_sound(&self) -> String {
        "woof".to_string()
    }
}

Addendum

只是为了澄清,我有两个问题:

  1. 为什么这不起作用? ...这在已接受的答案中得到了解决。
  2. 怎样才能一个type,而不是价值或参考,是短暂的吗? ...这在评论中得到了解决。剧透:type简单地存在,因为它是一个编译时概念。

实际上有很多类型“活得不够长”:所有类型都有生命周期参数。

如果我要介绍这种类型:

struct ShortLivedBee<'a>;
impl<'a> Animal for ShortLivedBee<'a> {}

ShortLivedBee不适用于任何生命周期,而仅对那些有效生命周期有效'a以及。

所以在你的情况下与界限

where T: Animal + 'static

唯一的ShortLivedBee我可以输入你的功能是ShortLivedBee<'static>.

造成这种情况的原因是在创建时Box<Animal>,您正在创建一个特征对象,它需要有一个关联的生命周期。如果不指定,则默认为'static。所以你定义的类型实际上是:

type RcAnimal = Rc<Box<Animal + 'static>>;

这就是为什么你的函数需要一个'static绑定被添加到T: 无法存储ShortLivedBee<'a> in a Box<Animal + 'static> unless 'a = 'static.


另一种方法是将生命周期注释添加到您的RcAnimal, 像这样:

type RcAnimal<'a> = Rc<Box<Animal + 'a>>;

并更改您的函数以明确生命周期关系:

fn new_rc_animal<'a, T>(animal: T) -> RcAnimal<'a>
        where T: Animal + 'a { 
    Rc::new(Box::new(animal) as Box<Animal>)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

参数类型可能寿命不够长? 的相关文章

随机推荐