如何将Rust中的可变引用变为不可变引用?

59

我正在尝试在Rust中将一个可变向量转换为不可变向量。我以为这会起作用,但事实并非如此:

let data = &mut vec![];
let x = data;          // I thought x would now be an immutable reference

我如何将可变引用转换为不可变绑定?


这很有帮助...例如,考虑rand crate中的'partial_shuffle'函数,它接受一个可变引用...这没问题,因为它必须就地洗牌...但它也返回可变切片...这个问题困扰了我两天,编译器一直抱怨我无法使用原始引用,因为它说“不能有不可变引用,因为已经借用为可变”...但我找不到我在哪里做到了这一点,因为dataset.partial_shuffle()应该是唯一的,并且可变借用必须随着函数结束而结束。继续... - AdityaG15
回到第一行“它接受一个可变引用,...这没问题,因为它必须在原地洗牌...但它也返回可变切片”,我没有关注到这一点,所以在这种情况下,如果我现在不需要返回的随机切片是可变的,我可以将它们转换为不可变的...从中得出的教训是:在阅读 Rust 文档时,要关注返回类型 :) - AdityaG15
2个回答

71

解除引用,然后重新引用该值:

fn main() {
    let data = &mut vec![1, 2, 3];
    let x = &*data;
}

根据你的代码,你应该阅读在变量名前面和冒号后面使用`mut`的区别是什么?。你的变量data已经是不可变的,但它包含一个可变引用。你不能重新分配data,但可以更改指向的值。

我怎样才能将可变引用变为不可变绑定?

它已经是一个不可变绑定了,因为你无法更改data的值。


这段代码在一个返回 Vec<String> 的函数中。如果我返回 &*data,会出现错误 expected struct std::vec::Vec, found reference。如果我返回 *data,会出现错误 cannot move out of borrowed content。这是借用检查器的问题吗?我解决这个问题的方法是返回 data.clone(),但我试图让它更高效,但我认为借用检查器可能不允许这样做,因为我在函数中创建了向量。也许我表达的不太对,但我如何从 data 中获取 Vec<String> 呢? - jbrown
1
@jbrown听起来你是想说你想要let mut data = vec![1, 2, 3]; return data; - Shepmaster
是的,这就是我想要的。谢谢。我会重新阅读关于可变性的 Rust 文档。 - jbrown

8
现在可行的另一种解决方案是指定x的类型:
fn main() {
    let data = &mut vec![1, 2, 3];
    let x: &_ = data;
    println!("{x:?}");
    // This will fail as x immutable
    // *x = vec![]
}

当你没有指定类型时,编译器会假设你想要相同的类型,这恰好是一个&mut Vec<_>


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