生命周期绑定会改变引用的类型吗?

问题描述 投票:0回答:1

我最近开始学习 Rust,在读完这本书后刚刚读完LifetimeKata。我觉得我理解了所有内容,除了第 9 章中的brainteaser,它引用了 rustc 的 GitHub issue

本质上,以下示例尽管看起来很合理,但无法编译。

use std::collections::HashSet;

struct Difference<'fst, 'snd>(Vec<&'fst str>, Vec<&'snd str>);

fn diffwords<'fst, 'snd>(lhs: &'fst str, rhs: &'snd str) -> Difference<'fst, 'snd> {
    let lhs: HashSet<&str> = lhs.split(' ').collect();
    let rhs: HashSet<&str> = rhs.split(' ').collect();
    Difference(
        lhs.difference(&rhs).copied().collect(),
        rhs.difference(&lhs).copied().collect(),
    )
}

fn main() {
    let lhs = String::from("I love the surf and the sand.");

    let res = {
        let rhs = String::from("I hate the surf and the sand.");
        diffwords(&lhs, &rhs).0
    };

    assert_eq!(res, vec!["love"]);

    let res = {
        let rhs = String::from("I love the snow and the sand.");
        diffwords(&rhs, &lhs).1
    };

    assert_eq!(res, vec!["surf"]);
}

这个评论似乎与GitHub问题的作者一致,即

HashSet<T, S>::difference()
的实现存在问题,但提到它不太可能被修复,以保持与以前的Rust版本的向后兼容性。同时,另一个comment似乎在说,该行为完全符合
difference()
方法的签名(复制如下),其中
Self
在本例中是
HashSet<T, S>

fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S>

我的困惑源于第二位评论者的言论。

API 仅适用于相同类型

T
,即对于引用类型,两个哈希集上的生命周期应该相同。

我是否正确理解第二个评论者建议同一类型的两个引用实际上是不同的类型,如果它们具有不同的生命周期界限?换句话说,

&'a T
&'b T
是两种不同的类型吗?如果是这样,为什么?

rust lifetime
1个回答
0
投票

您的困惑可能来自于这样一个事实:在很多情况下,编译器能够从

&'a T
隐式转换为
&'b T
(例如,如果
'b
'a
短)。但它们仍然是不同的类型,编译器不能总是在它们之间进行转换。例如:

fn uses_static (_foo: &'static i32) {}

fn calls_static<'a> (foo: &'a i32) {
    uses_static (foo);
}

上面的代码会导致“引用的生存时间不够长”错误,因为

&'a i32
&'static i32
不同。

另一方面:

fn uses_two_refs<'b> (_x: &'b i32, _y: &'b i32) {}

fn uses_one_ref<'a> (x: &'a i32) {
    let y = 0;    // This has lifetime `'b` strictly shorter than `'a`
    uses_two_refs (x, &y);
}

在第二个示例中,

&'a i32
&'b i32
是不同的类型,因此对
uses_two_refs (x, &y)
的调用应该会失败,因为
x
&y
具有不同的生命周期。但在这种情况下,编译器能够将
x
隐式转换为
&'b i32
类型,因为
'b
'a
短。

另请参阅 Rust 参考的“子类型化和方差” 章节。

© www.soinside.com 2019 - 2024. All rights reserved.