Here are two code snippets, but they show a different behavior and I couldn't understand what's going on in there. Their main function is identical. If the borrowing and ownership concept applies to one code (i.e to code 2) why not to another code i.e (code 1)?
code 1:
This code compiles with no errors and prompt the result.
fn main() {
let mut s = String::from("Hello world");
let result = first_word(&s);
s.clear();
println!("result:{:#?}", result);
}
fn first_word(s: &String) -> usize {
let s = s.as_bytes();
//println!("{:?}",s);
for (i, &item) in s.iter().enumerate() {
if item == 32 {
return i;
}
}
s.len()
}
Code 1 Output :
Finished dev [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/rust_Slices`
result:5
Code 2: This code won't compile and gives an error.
fn main() {
let mut s = String::from("Hello world");
let result = first_word(&s);
s.clear();
println!("{:#?}", result);
}
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
Code 2 Output:
cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:4:4
|
3 | let result = first_word(&s);
| -- immutable borrow occurs here
4 | s.clear();
| ^^^^^^^^^ mutable borrow occurs here
5 | println!("{:#?}",result);
| ------ immutable borrow later used here