Anatolii Kosorukov
Anatolii Kosorukov

Reputation: 960

Why does a slice starting at the length of a string not panic?

fn main() {
    let s = String::from("hello");
    let hello = &s[5..];
    println!("{}", hello);
}

Why does this code run without a panic? I think this is a condition where the index goes beyond the size of the content. The output of this code example shows nothing.

Upvotes: 9

Views: 1773

Answers (1)

Peter Hall
Peter Hall

Reputation: 58695

Ranges in Rust do not include the upper bound (unless you use the ..= range constructor). That means that ranges like 2..2 are zero length: "start at 2 and take each element up to, but not including 2". When the length is 5, 5..5 and 5.. are equivalent.

While it doesn't seem to make much sense to start a range past the last element, it is convenient that this works this way. For example, if you were taking ever shrinking ranges:

for i in 0 .. s.len() + 1 {
    println!("slice = {:?}", &s[i ..]);
}

Outputs:

slice = "hello"
slice = "ello"
slice = "llo"
slice = "lo"
slice = "o"
slice = ""

It would be annoying if you had to handle the last, empty slice, case separately.

But going further past the length of the data will cause a panic. There's no reason why you would intentionally have written s[6..6] when the string's length is 5.

Upvotes: 17

Related Questions