str::is_ascii¶
Level: reference · for working programmers
One line: true if every byte is below 128 — the precondition the whole ascii family is asking about.
Stable since 1.23.0. Usable in a const context.
A linear scan, const, and cheap because it needs no decoding: valid UTF-8 is ASCII exactly when no byte has its high bit set.
Its value is as a guard. to_ascii_lowercase, eq_ignore_ascii_case, trim_ascii and split_ascii_whitespace are all correct-and-fast on ASCII and quietly wrong on anything else — this is how you find out which you have before choosing.
It is also the fastest way to know that byte length equals character length: for ASCII, len() and chars().count() agree, and every byte offset is a character boundary.
Example¶
str_is_ascii.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
for s in ["hello", "héllo", "", "123!@#"] {
println!("{:<8} ascii={}", format!("{s:?}"), s.is_ascii());
}
// The guard that picks the right family.
for s in ["Content-Type", "Größe"] {
let lowered = if s.is_ascii() { s.to_ascii_lowercase() } else { s.to_lowercase() };
println!("{:<14} -> {lowered:?}", format!("{s:?}"));
}
// For ASCII, the two rulers agree and every offset is a boundary.
let a = "hello";
println!("{} {} {}", a.len(), a.chars().count(),
(0..=a.len()).all(|i| a.is_char_boundary(i)));
// const.
const TOKEN: &str = "GET";
const OK: bool = TOKEN.is_ascii();
println!("{OK}");
}
Verified output of str_is_ascii.rs — regenerated by tools/run_examples.py, never hand-typed.
"hello" ascii=true
"héllo" ascii=false
"" ascii=true
"123!@#" ascii=true
"Content-Type" -> "content-type"
"Größe" -> "größe"
5 5 true
true
See also¶
str::eq_ignore_ascii_case— one of the methods this guardsstr::to_ascii_lowercase— anotherstr::trim_ascii— anotherstr::len— equals the character count exactly when this is true
str::is_ascii in the standard library ↗
Po polsku¶
Dla polskiego tekstu ta metoda zwraca false prawie zawsze — i właśnie dlatego jest przydatna: „Gdańsk” czy „Łódź” zawierają bajty powyżej 127, więc cała rodzina *_ascii (to_ascii_lowercase, eq_ignore_ascii_case, trim_ascii, split_ascii_whitespace) zostawi te litery nietknięte. Nie zgłosi przy tym żadnego błędu, po prostu przepuści „Ł” bez zmiany, a to najbardziej podstępny rodzaj pomyłki, bo testy na słowie „hello” przechodzą bez zarzutu. Stąd wzorzec z przykładu: if s.is_ascii() { s.to_ascii_lowercase() } else { s.to_lowercase() } — szybka ścieżka tam, gdzie wolno, poprawna wszędzie indziej. Drugi zysk jest taki, że is_ascii() równe true gwarantuje, że len() w bajtach zgadza się z liczbą znaków i każde przesunięcie jest granicą znaku — czego przy polskich literach nie wolno założyć nigdy.
Szukaj po polsku: polskie znaki diakrytyczne w Ruscie · ASCII a UTF-8 · rust is_ascii to_ascii_lowercase · rust to_lowercase unicode