str::to_lowercase¶
Level: reference · for working programmers
One line: A new String lowercased by the full Unicode rules — which can change the length, and is context-sensitive for Greek sigma.
Stable since 1.2.0.
It allocates, because the result need not fit: case mapping is not a per-byte or even a per-character operation. Three facts follow, and each one breaks a plausible assumption:
- The length can change.
"İ"(Latin capital I with dot above, 2 bytes) lowercases to 3 bytes. - It is context-sensitive. A Greek capital sigma lowercases to
ςat the end of a word andσelsewhere —"ΣΣ".to_lowercase()is"σς", two different characters from the same input character. - It is not locale-aware. Turkish requires dotless
ıfor a lowercasedI;stdgivesi, because a locale-correct answer needs a locale, andstrhas none. If you need Turkish, you need a crate.
For case-insensitive comparison, prefer eq_ignore_ascii_case when the data is ASCII — it allocates nothing. Lowercasing both sides works for Unicode but is not the same as proper caseless matching, which needs case folding rather than case mapping.
Example¶
str_to_lowercase.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
println!("{:?}", "Hello World".to_lowercase());
// The length can change.
let dotted = "\u{0130}"; // LATIN CAPITAL LETTER I WITH DOT ABOVE
println!("{} bytes -> {} bytes", dotted.len(), dotted.to_lowercase().len());
// Context-sensitive: one input character, two different outputs.
println!("{:?}", "ΣΣ".to_lowercase());
println!("{:?}", "ΟΔΟΣ".to_lowercase());
// Not locale-aware: Turkish would want 'ı' here.
println!("{:?}", "I".to_lowercase());
// Allocates; the original is untouched.
let original = "MiXeD";
let lowered = original.to_lowercase();
println!("{original:?} {lowered:?}");
// Case-insensitive comparison, ASCII and otherwise.
println!("{}", "HELLO".eq_ignore_ascii_case("hello"));
println!("{}", "ΑΒΓ".to_lowercase() == "αβγ".to_lowercase());
}
Verified output of str_to_lowercase.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
str::to_uppercase— the other direction, with its own length surprisestr::to_ascii_lowercase— the ASCII-only version, which cannot change lengthstr::eq_ignore_ascii_case— comparison without allocatingstr::make_ascii_lowercase— in place, no allocation
str::to_lowercase in the standard library ↗
Po polsku¶
Dla polszczyzny to jest właśnie ta metoda, i da się powiedzieć wprost dlaczego: pełne reguły Unicode obejmują komplet naszych znaków diakrytycznych ("ŻÓŁW".to_lowercase() daje "żółw"), a to, że metoda nie zna ustawień lokalnych (locale) — co psuje sprawę tureckiemu I, bo std zwraca i zamiast ı — polskiemu nie szkodzi w niczym, ponieważ polski nie ma reguł zależnych od języka. Płaci się za to trzema niespodziankami, których wersja ASCII nie ma: metoda alokuje nowy String, długość może się zmienić ("İ" zajmuje 2 bajty, a po zamianie na małe litery 3) i wynik bywa zależny od kontekstu — greckie "ΣΣ" daje "σς", dwa różne znaki z dwóch takich samych. Praktyczny wniosek przy polskim tekście jest jeden: eq_ignore_ascii_case tu nie zadziała ("ŁÓDŹ".eq_ignore_ascii_case("łódź") to false, bo ta metoda porównuje wielkość liter wyłącznie w ASCII), trzeba zamienić na małe litery obie strony — pamiętając, że to nadal odwzorowanie wielkości liter, a nie pełne case folding.
Szukaj po polsku: małe litery a polskie znaki diakrytyczne · porównywanie bez rozróżniania wielkości liter · rust to_lowercase · rust case folding vs case mapping