I am learning Rust and I've encountered this when I was trying out examples:
fn main() {
let x: &str = "hello"; // We created a string slice, `&str`
let y: &str = x[2..4]; // I was expecting `y` to be `&str` as well
// let y: str = x[2..4]; // `y` is actually a str (DST)!
let z: &str = &x[2..4]; // This gives me what I expected!
println!("str value: {}", z);
}
I am fairly confused in the first place; wasn't x
a slice already? Why would I need to append the ampersand again in the last statement to make z a string slice (which in my mind it looks like &(&x)
or just &&x
)?
Related content that'd help you get grasp of the answer:
I am a bit stunned in the first place; wasn't x a slice already?
Yes?
why would I need to append the ampersand again in the last statement to make z a string slice?
Because that's how indexing is defined in the language.
container[index]
is actually syntactic sugar for*container.index(index)
[...]. This allows nice things such aslet value = v[index]
if the type of value implementsCopy
.
And that's why you have to re-reference owned types or DSTs coming out of an indexing operation.