I can’t understand why I am getting this error below:
`
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
In the code:
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);
}
`
I understand that I borrowed the ‘s’ in line 7 ‘unwrap’, but after borrow it I used clone and have no more references to the borrowed value ‘s’. So I would like to know why rust don’t "drop" the borrow in this case, and a solution on how I could perform this feature (modify a string and have the old string version in some variable).
Thanks.
I have tried to use ‘as_ref’ but things are becoming more complex and I think I am missing something, so I am trying to understand that so I can procced with rust studying.
>Solution :
First, you probably want 0..1
instead of 0..0
. In Rust, and most other programming languages, range definitions are inclusive on the lower end and exclusive on the upper end.
Next, s.get(0.11).unwrap()
will be of type &str
, i.e., a string slice. Cloning that will just copy the reference. See here: What happens when you clone a `&str`?
And because of that, cloning won’t "release" the borrow. Instead, you’ll need to create a new, owned string, which would be done via to_string()
.
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);
}