Question
In Rust, String::len() returns the number of bytes in the string, not the number of characters. This can be confusing when working with Unicode text.
For example:
let s = String::from("ラウトは難しいです!");
println!("{}", s.len()); // returns 30
The string contains 10 Unicode scalar values, but len() returns 30 because the text is encoded as UTF-8 and each character uses multiple bytes.
I found that this gives the character count I expect:
let count = s.chars().count();
println!("{}", count); // returns 10
Is there any built-in method on String that returns the number of characters directly, other than using s.chars().count()?
Short Answer
By the end of this page, you will understand why Rust strings report their length in bytes, how to count Unicode scalar values with chars().count(), and when that still differs from what users think of as a “character”. You will also learn the practical trade-offs between byte length, char count, and grapheme cluster count.
Concept
Rust String values are stored as UTF-8. UTF-8 is a variable-width encoding, which means:
- Some characters use 1 byte.
- Others use 2, 3, or 4 bytes.
Because of this, Rust's String::len() returns the number of bytes, not the number of human-readable characters.
let s = "hello";
println!("{}", s.len()); // 5 bytes
let s = "ラウト";
println!("{}", s.len()); // more than 3 bytes
In Rust, there are three different ideas that beginners often mix up:
- Bytes: the raw UTF-8 data stored in memory
charvalues: Unicode scalar values- Grapheme clusters: what a user usually sees as one character on screen
For many tasks, s.chars().count() is the correct answer if you want the number of Unicode scalar values. There is no special built-in String method like char_len() that does this directly. The standard Rust approach is:
Mental Model
Think of a Rust string like a sentence stored in boxes of varying sizes.
len()asks: how many boxes are being used?chars().count()asks: how many Unicode symbols are stored?- Grapheme counting asks: how many symbols does a person visually see?
These are not always the same.
For example, one visible symbol on screen can be made of:
- one byte
- several bytes
- one
char - multiple
charvalues combined
So when working with strings in Rust, the first question is not “How long is this string?” but rather:
Long in what unit?
Syntax and Examples
The most common string length-related operations in Rust are:
let s = String::from("こんにちは");
println!("bytes: {}", s.len());
println!("chars: {}", s.chars().count());
Example 1: ASCII text
let s = String::from("hello");
println!("bytes: {}", s.len());
println!("chars: {}", s.chars().count());
Output:
bytes: 5
chars: 5
For plain ASCII, bytes and chars are the same.
Example 2: Japanese text
let s = String::from();
(, s.());
(, s.().());
Step by Step Execution
Consider this example:
let s = String::from("aé日");
println!("bytes = {}", s.len());
println!("chars = {}", s.chars().count());
Let's trace it.
Step 1: Create the string
let s = String::from("aé日");
This string contains:
aé日
Step 2: Count bytes with len()
s.len()
In UTF-8:
auses 1 byteéuses 2 bytes
Real World Use Cases
Measuring storage or network size
If you are checking payload size, file size, database limits, or protocol limits, use:
s.len()
This tells you how many bytes the string uses.
Validating a maximum number of Unicode characters
If a rule says “maximum 50 Unicode characters”, use:
s.chars().count()
Example:
if username.chars().count() > 50 {
println!("Username is too long");
}
Limiting what users see on screen
For UI text, emojis, accented characters, and combined symbols, visible length may differ from chars().count(). In that case, grapheme clusters are more appropriate.
Processing multilingual text
When parsing international input, avoid assuming one byte equals one character. Rust's string model helps prevent those mistakes.
Safe iteration over text
Instead of indexing strings directly, Rust developers commonly use:
chars()for Unicode scalar values
Real Codebase Usage
In real Rust projects, developers usually choose string length logic based on the requirement rather than looking for one universal "length" method.
Common patterns
Validation
fn is_valid_name(name: &str) -> bool {
let count = name.chars().count();
count >= 2 && count <= 30
}
This is common in forms, APIs, and CLI tools.
Byte-size guards
fn fits_in_header(value: &str) -> bool {
value.len() <= 256
}
Useful when protocols or storage systems define byte limits.
Early returns
fn validate_message(msg: &str) -> Result<(), String> {
if msg.is_empty() {
return (.());
}
msg.().() > {
(.());
}
(())
}
Common Mistakes
Mistake 1: Assuming len() means character count
Broken expectation:
let s = "こんにちは";
assert_eq!(s.len(), 5); // wrong
Why it fails:
len()returns bytes, not Unicode scalar values.
Correct approach:
assert_eq!(s.chars().count(), 5);
Mistake 2: Assuming chars().count() is user-visible length
let s = "e\u{301}";
println!("{}", s.chars().count());
This may print 2, even though the user may see one character.
Avoid it by clarifying your requirement:
- Need Unicode scalar values? Use
Comparisons
| Task | Recommended Rust approach | What it measures | Notes |
|---|---|---|---|
| Get raw storage length | s.len() | Bytes | Fast and built-in |
| Count Unicode scalar values | s.chars().count() | char values | Standard-library solution |
| Count user-visible characters | s.graphemes(true).count() | Grapheme clusters | Requires unicode-segmentation |
| Iterate over raw encoded data | s.bytes() | Bytes | Useful for low-level work |
| Iterate over Unicode scalar values |
Cheat Sheet
// Bytes in UTF-8 string
s.len()
// Unicode scalar value count
s.chars().count()
// First Unicode scalar value
s.chars().next()
Rules to remember
String::len()returns bytes, not characters.- Rust strings are UTF-8.
- A
charin Rust is a Unicode scalar value. - One visible character on screen may be made of multiple
charvalues. - There is no built-in
Stringmethod likechar_len(). - The standard way to count scalar values is:
s.chars().count()
Edge cases
- ASCII text: byte count and char count are often the same.
- Non-ASCII text: byte count is often larger.
- Combined Unicode symbols: visible count may differ from
chars().count().
Performance note
len()is cheap.
FAQ
Does Rust have a built-in method to count characters in a String?
Not as a dedicated String method. The standard approach is s.chars().count().
Why does String::len() return bytes instead of characters?
Because Rust strings are stored as UTF-8, and byte length is the direct size of the underlying data.
Is chars().count() the same as the number of visible characters?
Not always. It counts Unicode scalar values, which can differ from what users see on screen.
What should I use for user-visible character counts in Rust?
Use grapheme cluster counting, typically with the unicode-segmentation crate.
Is chars().count() slower than len()?
Yes. len() is constant time, while chars().count() must iterate through the string.
Why can't I index a Rust string like s[0]?
Because UTF-8 characters have variable byte lengths, so direct character indexing would be ambiguous and unsafe.
Should I use String or for counting characters?
Mini Project
Description
Build a small Rust text analyzer that reports three different kinds of string length: bytes, Unicode scalar values, and whether the string is empty. This project helps reinforce that “string length” depends on what exactly you are measuring.
Goal
Create a program that accepts a few example strings and prints their byte length and character count correctly.
Requirements
- Create a Rust program with at least three example strings, including ASCII and non-ASCII text.
- Print the original string for each example.
- Print the result of both
len()andchars().count(). - Add a simple validation message if the string has more than 10 Unicode scalar values.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.