rust 为什么在克隆后仍存在借用

e4yzc0pl  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(141)

我不明白为什么我得到这个错误如下:'

error[E0502]: cannot borrow `*s` as mutable because it is also borrowed as immutable
 --> src/main.rs:8:5
  |
7 |     let char_h = s.get(0..0).unwrap().clone();
  |                  ----------- immutable borrow occurs here
8 |     s.replace_range(0..0, "h");
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
9 |     println!("char before {char_h} string after {}", s);
  |                            ------ immutable borrow later used here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `q_line_out_of_scope` due to previous error

第一个月

fn main() {
    let mut s = String::from("Hello World!!");
    try_changes(&mut s);
}

fn try_changes(s: &mut String) {
    let char_h = s.get(0..0).unwrap().clone();
    s.replace_range(0..0, "h");
    println!("char before {char_h} string after {}", s);
}

'
我知道我借用了第7行“unwrap”中的“s”,但是在借用之后我使用了clone,并且不再引用借用的值“s”。所以我想知道为什么rust在这种情况下不“丢弃”借用,以及如何执行此功能的解决方案(修改字符串并在某个变量中使用旧的字符串版本)。谢谢。
我试过使用“as_ref”,但事情变得越来越复杂,我想我错过了一些东西,所以我试图了解这一点,这样我就可以进行生 rust 的研究。

ni65a41a

ni65a41a1#

首先,您可能希望使用0..1而不是0..0,在Rust和大多数其他编程语言中,范围定义在低端是包含的,在高端是排除的。
接下来,s.get(0.11).unwrap()的类型将是&str,即字符串切片. Cloning,它只复制引用。What happens when you clone a &str?
正因为如此,克隆不会“释放”借位,而是需要创建一个新的 owned 字符串,这将通过to_string()完成。
参见此处:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9ad9ccf4c23669a77b84c1615501afde

fn main() {
    let mut s = String::from("Hello World!!");
    try_changes(&mut s);
}

fn try_changes(s: &mut String) {
    let char_h = s.get(0..1).unwrap().to_string();
    s.replace_range(0..1, "h");
    println!("char before {} string after {}", char_h, s);
}

相关问题