gpt4 book ai didi

rust - 可变借用自动更改为不可变?

转载 作者:行者123 更新时间:2023-11-29 08:11:32 26 4
gpt4 key购买 nike

似乎u,一个可变的借用,在

let v = &*u;

uv 都是不可变的借用引用,所以它们都是允许的。

use std::ascii::AsciiExt;

fn show(a: &str) {
println!("a={}", a);
}

fn main() {
let mut t = String::new();
t.push('s');
let u = &mut t;
u.make_ascii_uppercase(); // u is really mutable here
let v = &*u; // u became immutable to allow this?
show(u); // both u and v are now accessible!
show(v);
}

输出:

a=S
a=S

如果我在之后尝试使用 u 作为可变借用

show(v);

编译器会记得

let v = &*u;

确实不允许:

cannot borrow `*u` as mutable because it is also borrowed as immutable

这是一个错误还是真的有一些“当不再需要可变性时自动将可变借用转换为不可变”原则?我正在使用 Rust 1.13.0。

最佳答案

可变引用可以被不可变地借用,但这不是这里发生的事情。

当用&构成引用时,你需要明确可变性;除非您指定 &mut 否则它将是一个不可变的引用。


您的示例可以简化为:

use std::ascii::AsciiExt;

fn main() {
let mut t = "s".to_string();
let u = &mut t;
u.make_ascii_uppercase();
let v = &*u;

let () = v;
}

最后一行是让编译器告诉我们(在错误消息中)v 的类型的技巧。它报告:

error[E0308]: mismatched types
--> <anon>:9:9
|
9 | let () = v;
| ^^ expected reference, found ()
|
= note: expected type `&std::string::String`
= note: found type `()`

这里有:

  • u:一个不可变绑定(bind),它是 t
  • 的可变借用
  • v:一个不可变绑定(bind),它是通过u
  • t的不可变再借用

但是,如果我将 v 行更改为 let v = &mut *u;,那么我将得到 expected type '&mut std::string: :String' 然后我们有:

  • u:一个不可变绑定(bind),它是 t
  • 的可变借用
  • v:一个不可变的绑定(bind),它是通过u
  • t的可变再借用

这里的重要概念是再借用,这就是&*u&mut *u 的意义所在。重新借用允许从现有引用形成新引用:

  • 重新借用访问最初借用的变量
  • 在重新借用的生命周期内,借用其形成的引用

再借规则比较简单,它们反射(reflect)了借规则:

  • 如果您从不可变引用开始:
    • 您只能将其作为不可变引用重新借用,如果您愿意,可以使用多个并发的不可变重新借用
  • 如果你从一个可变引用开始:
    • 您可以将其重新借用为可变引用,独占
    • 或者您可以将其作为不可变引用重新借用,如果您愿意,可以使用多个并发的不可变重新借用

有趣的是,重新借用的引用可以比其形成的引用存在的时间更长:

fn main() {
let mut t = "s".to_string();

let v;
{
let u = &mut t;
v = &mut *u;
}

v.make_ascii_uppercase();
show(v);
}

这是确保您可以从函数返回引用所必需的;当然。

因此,最终,重新借用会被编译器追踪到原始借用值;然而,由于重新借用机制,它允许形成对该原始值的不可变引用,即使可变引用在范围内......并且只需确保该可变引用在新的不可变引用的生命周期内不可用。


当函数采用引用时,编译器会自动在调用点引入具有适当可变性的重新借用;这就是 show 发生的情况:show(u) 实际上是 show(&*u),在持续时间内形成了一个新的不可变引用函数调用。

关于rust - 可变借用自动更改为不可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40654940/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com