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

Nam*_*ang 8 reference primitive-types rust

在Rust书的Lifetimes一章中,有一个例子:

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);
}
Run Code Online (Sandbox Code Playgroud)

他们为什么用x: &'a i32

我认为如果它只是在x: i32那时他们无法证明终身使用.但是,背后还有其他原因吗?是否有任何生产代码使用对i32等基本类型的不可变引用?

Vla*_*eev 11

在这种特殊情况下,原因确实是显示了生命的概念.但是,对于一般情况,我认为没有理由对基本类型进行不可变引用(当然,可变引用是另一回事),除非在通用代码中完成它:

struct Holder<'a, T> {
    r: &'a T
}

let x: i32 = 123;
let h: Holder<i32> = Holder { r: &x };
Run Code Online (Sandbox Code Playgroud)

在这里,如果你有这样的结构,你没有其他选择使用对a的引用i32.当然,该结构也可以与其他非原始和不可移动类型一起使用.

正如Shepmaster在评论中提到的那样,确实有一种情况你可以引用基本类型 - 它是引用的迭代器.请记住,通过约定(标准库遵循的)iter()方法,集合应该将引用的迭代器返回到集合中:

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

然后几乎所有迭代器上接受闭包的方法都会接受其参数为引用的闭包:

i.map(|n| *n + 1)  // n is of type &i32
Run Code Online (Sandbox Code Playgroud)

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