为什么要使用不可变的 i32 引用?

9
在Rust书籍的“生命周期”章节中,有一个例子:
struct Foo<'a> {
    x: &'a i32,
}

fn main() {
    let y = &5; // this is the same as `let _y = 5; let y = &_y;`
    let f = Foo { x: y };

    println!("{}", f.x);
}

为什么要使用x: &'a i32

我认为,如果只是x: i32,就不能展示生命周期的使用。不过,还有其他原因吗?有没有生产代码使用不可变引用指向像i32这样的原始类型?

1个回答

11
在这种情况下,目的确实是为了展示生命周期的概念。至于一般情况,除了在泛型代码中使用时(当然,可变引用是另一回事),我看不到将不可变引用应用于原始类型的理由:
struct Holder<'a, T> {
    r: &'a T
}

let x: i32 = 123;
let h: Holder<i32> = Holder { r: &x };

如果你有这样的结构,你别无选择,只能使用对的引用。当然,这个结构也可以与其他非原始和不可移动的类型一起使用。

正如Shepmaster在评论中提到的,确实存在一种情况,即对基本类型的引用 - 它是通过引用迭代器实现的。请记住,按照约定(标准库遵循的约定),集合上的iter()方法应返回对集合中引用的迭代器:

let v: Vec<i32> = vec![1, 2, 3, 4];
let i = v.iter();  // i is Iterator<Item=&i32>

几乎所有带有闭包参数的迭代器方法都可以接受参数为引用的闭包:

i.map(|n| *n + 1)  // n is of type &i32

请注意,这实际上是泛型更一般情况的结果。向量和切片可以包含任意类型,包括不可移动的类型,因此它们必须具有允许用户借用其内容的方法。


使用不可变参考作为观察者如何? - emlai
@zenith 观察的是什么?在存在未解除借用的情况下,您无法更改该值。 - Shepmaster
@Shepmaster 哦,完全忘记了那个。谢谢! - emlai
@Shepmaster,能否给个 &[i32] 的例子?非常感谢。 - nxh
@VladimirMatveev 当然没问题!只是切片和迭代器适配器是人们在现实世界中会遇到的原始引用的情况。 - Shepmaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接