简体   繁体   English

在实现Deref特征时无法推断生命周期参数的适当生命周期

[英]Cannot infer an appropriate lifetime for lifetime parameter while implementing Deref trait

I am trying to implement Deref for an enum: 我正在尝试为枚举实现Deref

use std::rc::Rc;
use std::ops::Deref;

pub trait tObject {
    fn name(&self) -> String;
    fn span(&self) -> u32;
}

pub struct t1 {
    pub name: String,
    pub bd: Option<String>,
    pub span: u32,
    pub label: Option<String>
}

pub struct t2 {
    pub name: String,
    pub vrf: Option<String>,
    pub span: u32,
    pub label: Option<String>,
    pub svi: u32
}

pub struct t3 {
    pub name: String,
    pub span: u32,
    pub label: Option<String>
}

impl tObject for t1 {
    fn name(&self) -> String {self.name.clone()}
    fn span(&self) -> u32 {self.span.clone()}
}

impl tObject for t2 {
    fn name(&self) -> String {self.name.clone()}
    fn span(&self) -> u32 {self.span.clone()}
}

impl tObject for t3 {
    fn name(&self) -> String {self.name.clone()}
    fn span(&self) -> u32 {self.span.clone()}
}

pub enum TType {
    t1(Rc<t1>),
    t2(Rc<t2>),
    t3(Rc<t3>)
}

impl Deref for TType {
    type Target = tObject;
    fn deref<'a>(&'a self) -> &'a tObject {
        match *self {
            TType::t1(ref x) => x as &t1,
            TType::t2(ref x) => x as &t2,
            TType::t3(ref x) => x as &t3
        }
    }
}

fn main() {
    let mut t1s: Vec<Rc<t1>> = Vec::new();
    let mut t2s: Vec<Rc<t2>> = Vec::new();
    let mut t3s: Vec<Rc<t3>> = Vec::new();

    let t_iter: Box<Iterator<Item=TType>> = Box::new(t1s.iter().map(|x| TType::t1(x.clone())).chain(
                                                t2s.iter().map(|x| TType::t2(x.clone())).chain(
                                                t3s.iter().map(|x| TType::t3(x.clone())))));
}

The compiler reports this error: 编译器报告此错误:

rustc 1.15.1 (021bd294c 2017-02-08)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting     requirements
  --> <anon>:53:5
   |
53 |       fn deref<'a>(&'a self) -> &'a tObject {
   |  _____^ starting here...
54 | |         match *self {
55 | |             TType::t1(ref x) => x as &t1,
56 | |             TType::t2(ref x) => x as &t2,
57 | |             TType::t3(ref x) => x as &t3
58 | |         }
59 | |     }
   | |_____^ ...ending here
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 53:42...
  --> <anon>:53:43
   |
53 |       fn deref<'a>(&'a self) -> &'a tObject {
   |  ___________________________________________^ starting here...
54 | |         match *self {
55 | |             TType::t1(ref x) => x as &t1,
56 | |             TType::t2(ref x) => x as &t2,
57 | |             TType::t3(ref x) => x as &t3
58 | |         }
59 | |     }
   | |_____^ ...ending here
note: ...so that method type is compatible with trait (expected fn(&TType) -> &tObject + 'static, found     fn(&TType) -> &tObject)
  --> <anon>:53:5
   |
53 |       fn deref<'a>(&'a self) -> &'a tObject {
   |  _____^ starting here...
54 | |         match *self {
55 | |             TType::t1(ref x) => x as &t1,
56 | |             TType::t2(ref x) => x as &t2,
57 | |             TType::t3(ref x) => x as &t3
58 | |         }
59 | |     }
   | |_____^ ...ending here
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that method type is compatible with trait (expected fn(&TType) -> &tObject + 'static, found     fn(&TType) -> &tObject)
  --> <anon>:53:5
   |
53 |       fn deref<'a>(&'a self) -> &'a tObject {
   |  _____^ starting here...
54 | |         match *self {
55 | |             TType::t1(ref x) => x as &t1,
56 | |             TType::t2(ref x) => x as &t2,
57 | |             TType::t3(ref x) => x as &t3
58 | |         }
59 | |     }
   | |_____^ ...ending here   

If I make the return type of deref Self::Target instead of tObject , it compiles fine. 如果我将deref Self::Target的返回类型改为tObject ,则可以正常编译。 I do not understand this behaviour. 我不了解这种行为。

Here is a MCVE . 这是一个MCVE Programmers use these to help narrow down the scope of a problem. 程序员使用它们来帮助缩小问题的范围。 For example, this MCVE rules out anything being due to the use of the enum , the Rc , any of the methods in the trait, or any of the fields in the structs. 例如,此MCVE排除了由于使用enumRc ,特征中的任何方法或结构中的任何字段而导致的所有问题。 This allows us to focus on what is important: 这使我们可以专注于重要的事情:

use std::ops::Deref;

pub trait Trait {}

pub struct S {}
impl Trait for S {}

pub struct Container(S);

impl Deref for Container {
    type Target = Trait;

    // fn deref(&self) -> &Trait { // Fails!
    fn deref(&self) -> &Self::Target { // Works!
        &self.0
    }
}

From the code, we can intuit that, somehow, Trait and Self::Target are not the same type. 从代码中,我们可以直观地看出TraitSelf::Target 不是同一类型。 It's a bit tricky to see the type here, but this code prints out the type as a compiler error: 在这里看到类型有点棘手,但是此代码将类型打印为编译器错误:

fn deref(&self) -> &Self::Target {
    let a: Self::Target;
    &self.0
}
error[E0277]: the trait bound `Trait + 'static: std::marker::Sized` is not satisfied

We don't actually care about the error, but we've discovered the type: Trait + 'static . 我们实际上并不关心该错误,但是我们发现了以下类型: Trait + 'static Let's see what happens if we try something like that: 让我们看看如果尝试这样的话会发生什么:

fn deref(&self) -> &(Trait + 'static) {
    &self.0
}

This compiles. 这样编译。

In case you are unfamiliar with this syntax, there are plenty of questions about it. 如果您不熟悉此语法,则有很多疑问。 Here are some: 这里有一些:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法推断生命周期参数克隆特征对象的适当生命周期 - Cannot infer an appropriate lifetime for lifetime parameter cloning trait object 将结构转换为具有生存期的特征得到“由于需求冲突,无法为生存期参数&#39;a&#39;推断适当的生存期” - casting struct to trait with lifetime got “cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements” 无法推断出合适的生命周期 - cannot infer an appropriate lifetime for lifetime 无法为结构内具有相同生命周期的多个引用推断生命参数的适当生命周期 [E0495] - cannot infer an appropriate lifetime for lifetime parameter with multiple references with the same lifetime inside a struct [E0495] 作为函数参数的闭包“由于需求冲突而无法推断出适当的寿命” - Closure as function parameter “cannot infer an appropriate lifetime due to conflicting requirements” Rust – 从 trait 方法返回 trait 对象时无法推断出适当的生命周期 - Rust – cannot infer an appropriate lifetime when returning trait object from trait method 由于对由具有 Serde Deserialize 的枚举组成的结构的要求相互冲突,因此无法为生命周期参数“de”推断合适的生命周期 - cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements for struct made of enums with Serde Deserialize "由于要求冲突,无法推断函数调用中生命周期参数 &#39;_ 的适当生命周期" - cannot infer an appropriate lifetime for lifetime parameter '_ in function call due to conflicting requirements 在结构中存储闭包 - 无法推断出适当的寿命 - Storing a closure in a structure — cannot infer an appropriate lifetime 无法为返回引用的闭包推断合适的生命周期 - Cannot infer an appropriate lifetime for a closure that returns a reference
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM