str::is_char_boundary¶
Level: reference · for working programmers
One line: Whether a byte offset is a legal slice endpoint — true at the start of a character, at len(), and nowhere else.
Stable since 1.9.0. Usable in a const context.
This is the predicate behind every string panic. &s[..i] is safe exactly when s.is_char_boundary(i) and i <= s.len(); the second is implied, since an out-of-range index returns false.
0 and len() are always boundaries, so an empty slice is always legal.
Use it to test an offset that arrived from elsewhere. When you want to repair one, floor_char_boundary and ceil_char_boundary move it to the nearest legal position instead — usually the better answer for truncating a display string, where refusing to truncate is not an option.
const fn, so a boundary assertion can be checked at compile time.
Example¶
str_is_char_boundary.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let s = "héllo"; // h=0, é=1..3, l=3, l=4, o=5, len=6
for i in 0..=s.len() + 1 {
println!("{i} -> {}", s.is_char_boundary(i));
}
// The predicate behind the panic.
for i in [1, 2, 3] {
let ok = s.is_char_boundary(i);
println!("&s[..{i}] {}", if ok { format!("= {:?}", &s[..i]) } else { "would panic".into() });
}
// Testing vs repairing.
let bad = 2;
println!("test: {}", s.is_char_boundary(bad));
println!("repair: {} down, {} up", s.floor_char_boundary(bad), s.ceil_char_boundary(bad));
// ASCII: every offset is a boundary.
let ascii = "hello";
println!("{}", (0..=ascii.len()).all(|i| ascii.is_char_boundary(i)));
}
Verified output of str_is_char_boundary.rs — regenerated by tools/run_examples.py, never hand-typed.
0 -> true
1 -> true
2 -> false
3 -> true
4 -> true
5 -> true
6 -> true
7 -> false
&s[..1] = "h"
&s[..2] would panic
&s[..3] = "hé"
test: false
repair: 1 down, 3 up
true
See also¶
str::floor_char_boundary— move a bad offset back to a legal onestr::ceil_char_boundary— move it forward insteadstr::get— slicing that refuses rather than panickingstr::char_indices— enumerating every boundary
str::is_char_boundary in the standard library ↗
Po polsku¶
To warunek stojący za najczęstszą paniką na łańcuchach znaków: &s[..i] jest legalne dokładnie wtedy, gdy s.is_char_boundary(i). Polski tekst trafia na niego od razu, bo każda litera z ogonkiem zajmuje dwa bajty — w przykładzie é rozciąga się na bajty 1..3, więc &s[..2] wchodzi w jego środek i program panikuje komunikatem end byte index 2 is not a char boundary; it is inside 'é' (bytes 1..3 of string). Warto rozdzielić dwa zadania: is_char_boundary sprawdza przesunięcie (dla indeksu spoza zakresu, jak 7 w wydruku, też zwraca false), a do naprawienia złego przesunięcia służą floor_char_boundary i ceil_char_boundary — to samo przesunięcie 2 cofają do 1 albo przesuwają w przód do 3. Przy skracaniu tekstu do wyświetlenia zwykle chcesz tej drugiej pary, bo „nie skracam” nie jest wtedy odpowiedzią.
Szukaj po polsku: granica znaku UTF-8 · skracanie tekstu z polskimi znakami · rust byte index is not a char boundary · rust floor_char_boundary