Start learning free

LESSON 63 OF 414 · STRINGS I

String Length in Rust: len() and Slicing from the End

Lesson Read the full explanation

We can get the length of a string using the .len() method like this:

let mut message = String::from("Hello world");

// Printing the length:
println!("{}", message.len()); // Output: 11

// Changing the message:
message += "!";

// Printing the new length:
println!("{}", message.len()); // Output: 12

Accessing characters from the end:

The length is useful for accessing characters from the end of a string.

Because strings are 0-indexed, the index of the last character is length - 1:

let message = String::from("Hello world");
let length = message.len();

// Printing the last character:
println!("{}", &message[length - 1..length]); // Output: d

// Printing the second to last character:
println!("{}", &message[length - 2..length - 1]); // Output: l

In general, if you want the nth last character, you use &message[length - n..length - n + 1].


Slicing characters from the end:

The length is also useful for slicing some characters from the end of a string:

let message = String::from("Hello world");
let length = message.len();

// Slicing last 4 characters:
let last_chars = &message[length - 4..];
println!("{}", last_chars); // Output: orld

// Slicing last 7 characters:
let last_chars = &message[length - 7..];
println!("{}", last_chars); // Output: o world

In general, if you want the last n characters, you use &message[length - n..].


Assignment
Follow the Coding Tutorial and let's practice with string length!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 3
    Ctrl + Enter to check

    RUST · STRINGS I

    String Length in Rust, explained

    Getting the length

    The method len() returns the length of a string:

    let mut message = String::from("Hello world");
    println!("{}", message.len());
    message += "!";
    println!("{}", message.len());
    
    11
    12
    

    The result is a usize, an unsigned integer. It can't be negative, and that matters as soon as you subtract from it.

    Length counts bytes

    In Rust, len() returns the number of bytes in the string's UTF-8 encoding, not the number of characters. For plain ASCII text, which covers English letters, digits, spaces and common punctuation, the two are equal. For other text they differ:

    Textlen()chars().count()
    "Hello world"1111
    "héllo"65
    "日本語"93

    Use len() when you want the size in bytes, or when you know the text is ASCII, as in this lesson. Use chars().count() when you want the number of characters; it has to walk through the whole string, so it is slower. An empty string has length 0, and is_empty() is the clearest way to test for it.

    Characters from the end

    Positions start at 0, so the last character is at position len() - 1. Rust strings can't be indexed by a single number, so you take a one-character slice from that position. A range with no end, such as length - 1.., runs to the end of the string:

    let message = String::from("Hello world");
    let length = message.len();
    println!("{}", &message[length - 1..length]);
    println!("{}", &message[length - 2..length - 1]);
    
    d
    l
    

    In general, the n-th character from the end is &message[length - n..length - n + 1].

    The "minus one" comes from counting. A string of length 11 has positions 0 to 10, so position 11 does not exist. The end of a range is excluded, which is why the one-character slice at the end can be written as length - 1..length or just length - 1..: both stop after the last byte. The same arithmetic works for any position counted from the end, and it never needs the string to be rewritten or reversed.

    Slicing the last n characters

    To take the last n characters, start at length - n and leave the end open:

    let message = String::from("Hello world");
    let length = message.len();
    let last_chars = &message[length - 4..];
    println!("{}", last_chars);
    let last_chars = &message[length - 7..];
    println!("{}", last_chars);
    
    orld
    o world
    

    The second let last_chars is a new variable that hides the first one. This is called shadowing and is allowed in Rust. Each slice is a borrowed &str, so nothing is copied.

    The lesson's exercise

    The starter code has message set to "I love pancakes", which has 15 characters. The exercise prints three things.

    1. The length. message.len() gives 15.
    2. The last character. The slice starts at message.len() - 1, which is position 14, and runs to the end. It prints s.
    3. The last five characters. The slice starts at message.len() - 5, which is position 10, and prints cakes.
    let message = "I love pancakes";
    println!("{}", message.len());
    println!("{}", &message[message.len() - 1..]);
    println!("{}", &message[message.len() - 5..]);
    
    15
    s
    cakes
    

    Here message is a &str rather than a String, and len() and slicing work the same on both.

    Gotchas

    • Empty strings. len() - 1 on an empty string is the unsigned subtraction 0 - 1. In a build with optimizations it wraps around to 18446744073709551615, and in a debug build it panics. Either way, the slice that follows panics because the position is out of bounds. Check is_empty() first.
    • Taking more than exists. length - 7 for a string of length 5 underflows the same way. Make sure n <= length before slicing.
    • Starting at the length. &message[message.len()..] is legal and gives an empty string, not the last character. That is one position too far, and the next lesson looks at it.
    • Non-ASCII text. A byte position computed from len() may fall inside a multi-byte character and panic. For such text, work with chars(), for example message.chars().last() gives Some('d') for "Hello world".

    Key takeaways

    • len() returns a usize holding the number of bytes.
    • The last position is len() - 1; the last n characters are &s[len() - n..].
    • Characters and bytes differ outside ASCII; use chars().count() for characters.
    • Subtracting from the length of a short or empty string is a classic source of bugs.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free