参数类型可能不够长? [英] Parameter type may not live long enough?

查看:42
本文介绍了参数类型可能不够长?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following code segment gives me an error:

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 的使用.类型怎么可能活得不够久?(游乐场)

What is the cause of the error? The only real difference seems to be the use of operator as. How can a type not live long enough? (playground)

// 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()
    }
}

<小时>

附录

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

Just to clarify, I had two questions:

  1. 为什么这不起作用?...在接受的答案中得到了解决.
  2. 相对于值或引用,类型如何是短暂的?......这在评论中得到了解决.剧透:类型只是存在,因为它是一个编译时概念.
  1. Why doesn't this work? ... which is addressed in the accepted answer.
  2. How can a type, as opposed to a value or reference, be shortlived? ... which was addressed in the comments. Spoiler: a type simply exists since it's a compile-time concept.

推荐答案

实际上有很多类型可以活得不够久":所有类型都有生命周期参数.

There are actually plenty of types that can "not live long enough": all the ones that have a lifetime parameter.

如果我要介绍这种类型:

If I were to introduce this type:

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

ShortLivedBee 对任何生命周期都无效,但仅对 'a 有效.

ShortLivedBee is not valid for any lifetime, but only the ones that are valid for 'a as well.

所以在你的情况下

where T: Animal + 'static

我可以输入您的函数的唯一 ShortLivedBeeShortLivedBee<'static>.

the only ShortLivedBee I could feed into your function is ShortLivedBee<'static>.

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

What causes this is that when creating a Box<Animal>, you are creating a trait object, which need to have an associated lifetime. If you do not specify it, it defaults to 'static. So the type you defined is actually:

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

这就是为什么您的函数要求将 'static 绑定添加到 T:不可能存储 ShortLivedBee<'a>Box 除非 'a = 'static.

That's why your function require that a 'static bound is added to T: It is not possible to store a ShortLivedBee<'a> in a Box<Animal + 'static> unless 'a = 'static.

另一种方法是为您的 RcAnimal 添加生命周期注释,如下所示:

An other approach would be to add a lifetime annotation to your RcAnimal, like this:

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

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

And change your function to explicit the lifetime relations:

fn new_rc_animal<'a, T>(animal: T) -> RcAnimal<'a>
        where T: Animal + 'a { 
    Rc::new(Box::new(animal) as Box<Animal>)
}

这篇关于参数类型可能不够长?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆