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

2024-02-04

在《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 等基本类型的不可变引用?


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

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

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

在这里,如果您有这样的结构,那么您别无选择,只能使用对i32。当然,这种结构也可以与其他非原始且不可移动的类型一起使用。

正如 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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么使用 i32 的不可变引用 的相关文章

随机推荐