2017-07-02 66 views
2

我刚刚开始学习来自Java/JavaScript背景的Rust,所以请耐心等待,因为我明显错过了我对生命时间的理解。我在生命中缺少什么?

fn main() { 
    struct Appearance<'a> { 
     identity:  &'a u64, 
     role:   &'a str 
    }; 
    impl<'a> PartialEq for Appearance<'a> { 
     fn eq(&self, other: &Appearance) -> bool { 
      self.identity == other.identity && self.role == other.role 
     } 
    }; 
    let thing = 42u64; 
    let hair_color = "hair color"; 
    let appearance = Appearance { 
     identity: &thing, 
     role: &hair_color 
    }; 
    let another_thing = 43u64;  
    let other_appearance = Appearance { 
     identity: &another_thing, 
     role: &hair_color 
    }; 
    println!("{}", appearance == other_appearance); 
} 

,因为编译器到达other_appearance,告诉我,another_thing不活足够长的时间这是给我一个编译错误。但是,如果我省略other_appearance的创建,程序编译并运行正常。为什么我得到这个错误?

回答

5

PartialEq trait有一个类型参数,用于指定右侧的类型。既然你没有指定它,它默认为与左侧相同的类型。这意味着双方被认为具有相同的寿命。 这会导致错误,因为another_thingappearance之前丢失,但other_appearance(保留对another_thing的引用)假定与appearance的寿命相同。

您可以通过在右手侧的不同生命周期解决这个问题:

impl<'a, 'b> PartialEq<Appearance<'b>> for Appearance<'a> { 
    fn eq(&self, other: &Appearance<'b>) -> bool { 
     self.identity == other.identity && self.role == other.role 
    } 
}; 
+0

这实际上很有趣,因为'#[derive(PartialEq)]'创建的实例与OP的问题相同。 –

+0

另一方面,由于这些值按照与它们声明相反的顺序被删除,所以也可以通过交换顺序来解决这个问题,即使用'other_appearance == appearance'而不是'appearance == other_appearance'。是的,Rust有几个疣子... –

+0

谢谢!我需要详细说明语法,即使我在概念上理解你所说的:) –

1

这与使用==语法结合糖时的终生推理/差异似乎是一个问题 - 请注意,替换与PartialEq::eq(&appearance, &other_appearance)工作的比较。我不知道这是否是一个已知的错误。

+0

奇怪。这一定是一个错误。而且这是特别令人惊讶的,因为当你''[派生(PartialEq)]'时,行为与OP的行为相同,这让我想知道它以前怎么没有被发现。 –