str::split_at¶
Level: reference · for working programmers
One line: Cuts the string in two at a byte offset, returning both halves — and panics if the offset is not a character boundary.
Stable since 1.4.0. Usable in a const context.
"hello".split_at(2) is ("he", "llo"). The argument is a byte index, not a character count, and the two failure modes are the same as slicing:
- out of range —
mid > len() - inside a character —
"héllo".split_at(2)panics, because byte 2 is the second half ofé
Both are run-time panics, not compile errors, which makes this one of the few string operations that can bring a program down on data it has never seen. split_at_checked is the same cut returning Option, and is the better default in any code handling text you did not write.
split_at(0) and split_at(len()) are legal and give an empty half.
Example¶
str_split_at.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
println!("{:?}", "hello".split_at(2));
println!("{:?}", "hello".split_at(0));
println!("{:?}", "hello".split_at(5));
// Byte offsets: 'é' occupies bytes 1 and 2, so only 1 and 3 are legal.
let s = "héllo";
for mid in 0..=s.len() {
let ok = s.is_char_boundary(mid);
println!("mid {mid} boundary={ok:<5} {:?}", if ok { Some(s.split_at(mid)) } else { None });
}
// The safe form, which reports the refusal instead of panicking.
println!("{:?}", s.split_at_checked(2));
println!("{:?}", s.split_at_checked(99));
}
Verified output of str_split_at.rs — regenerated by tools/run_examples.py, never hand-typed.
("he", "llo")
("", "hello")
("hello", "")
mid 0 boundary=true Some(("", "héllo"))
mid 1 boundary=true Some(("h", "éllo"))
mid 2 boundary=false None
mid 3 boundary=true Some(("hé", "llo"))
mid 4 boundary=true Some(("hél", "lo"))
mid 5 boundary=true Some(("héll", "o"))
mid 6 boundary=true Some(("héllo", ""))
None
None
See also¶
str::split_at_checked— the same cut, without the panicstr::is_char_boundary— testing the offset firststr::floor_char_boundary— nudging a bad offset to a legal onestr::split_at_mut— the mutable version
str::split_at in the standard library ↗
Po polsku¶
split_at dostaje offset w bajtach, a nie numer znaku, i dla polskiego tekstu to różnica jak najbardziej praktyczna: w UTF-8 każde ą, ć, ę, ł, ń, ó, ś, ź, ż zajmuje po dwa bajty, więc w "żółw" (7 bajtów) legalne cięcia to 0, 2, 4, 6 i 7 — a split_at(3) ląduje w środku ó i program panikuje, dokładnie tak jak "héllo".split_at(2) z przykładu wyżej, gdzie tabelka pokazuje mid 2 boundary=false. To nie jest błąd kompilacji, tylko panika w czasie działania, więc taki kod przechodzi wszystkie testy na danych ASCII i wywraca się dopiero na tekście od użytkownika. W kodzie dotykającym cudzego tekstu domyślnie sięgaj więc po split_at_checked (zamiast panikować, zwraca None) albo sprawdź offset przez is_char_boundary; skrajne cięcia split_at(0) i split_at(len()) są legalne i dają pustą połówkę.
Szukaj po polsku: polskie znaki zajmują dwa bajty · granica znaku w łańcuchu znaków · rust byte index is not a char boundary · rust split_at panic utf8