fn strtok<'a>(s: &'a str, delimiter: char) -> &'a str {
&s[0..5]
}
fn main() {
let mut x = "hello world";
let hello = strtok(&x, ' ');
//println!("{}", hello);
let mut z = &mut x;
println!("{}", hello);
}
In the snippet borrow of x has same lifetime as hello which will last till last usage. And we are trying to borrow x mutably in between which shouldn't compile.
this is immutably borrowing 'x' and returning same with 'a doesn't immutable borrow happens to be for 'a lifetime which will last till println!("{}", hello).
&str is always immutable no matter what, only it has a different slice of "hello world", in fact the real data is in .data section. Another thing to point out is that &str has the trait copy, thats why you really don't move x to hello
let hello = strtok(&x, ' ');
let hello = strtok(&**&x, ' ');
Due to deref coercion. The latter pattern is also called reborrowing and happens implicitly in many places.
Reborrows don't borrow the intermediate references themselves, and their outer lifetime is limited only by the inner-most shared reference when there is one. In that case, in effect it acts like copying the shared reference. So effectively you passed in a copy of x.
(If x is not 'static, it still works. It works with x: &String too.)