str::substr_range¶
Level: reference · for working programmers
One line: The byte range a sub-slice occupies within this string, or None if it is not part of it — an identity question, not a search.
Stable since 1.98.0.
This does not look for matching text. It compares addresses: it answers "is this &str a view into that &str, and if so, where". A slice with identical contents taken from a different allocation gives None.
That is the difference from find, which searches by content and would happily report an offset for an unrelated string that happens to match.
It is the safe replacement for the pointer arithmetic people write with as_ptr: subtracting two addresses to recover an offset does the same job with none of the guarantees.
The realistic use is in parsers and tokenizers. Once a lexer has produced a token as a &str borrowed from the input, this recovers its position for an error message — without threading offsets through every function.
Example¶
str_substr_range.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let text = "let x = 42;";
let token = &text[8..10];
println!("{token:?} at {:?}", text.substr_range(token));
// Identity, not content: an equal string from elsewhere is not part of it.
let elsewhere = String::from("42");
println!("{:?}", text.substr_range(elsewhere.as_str()));
println!("but find() matches by content: {:?}", text.find("42"));
// Recovering a token's position for an error message.
for tok in text.split_whitespace() {
let at = text.substr_range(tok).map(|r| r.start);
println!("{:<5} column {:?}", format!("{tok:?}"), at);
}
// The whole string is a substring of itself.
println!("{:?}", text.substr_range(text));
}
Verified output of str_substr_range.rs — regenerated by tools/run_examples.py, never hand-typed.
"42" at Some(8..10)
None
but find() matches by content: Some(8)
"let" column Some(0)
"x" column Some(4)
"=" column Some(6)
"42;" column Some(8)
Some(0..11)
See also¶
str::find— searching by content instead of identitystr::as_ptr— the unsafe pointer arithmetic this replacesstr::char_indices— offsets while iterating rather than afterwardsstr::split_whitespace— a common source of the borrowed tokens
str::substr_range in the standard library ↗
Po polsku¶
Nazwa myli i na tym polega cała pułapka tej metody: substr_range niczego nie szuka. Porównuje adresy — pyta, czy podany wycinek łańcucha (string slice) jest widokiem na ten właśnie łańcuch, i jeśli tak, w którym miejscu; dlatego text.substr_range(elsewhere.as_str()) zwraca None, choć elsewhere to dosłownie "42", podczas gdy text.find("42") w linijce obok daje Some(8). Chodzi więc o tożsamość, a nie o treść, i to jest dokładnie to pytanie, które zadaje się w lekserze: token wypożyczony z wejścia sam wie, gdzie leży, więc nie trzeba przeciskać przesunięć przez wszystkie funkcje po drodze, żeby wypisać numer kolumny w komunikacie o błędzie. Metoda jest stabilna dopiero od 1.98.0 i zastępuje ręczne odejmowanie adresów po as_ptr — ten sam wynik, tylko bez unsafe.
Szukaj po polsku: podłańcuch a tożsamość referencji · pozycja tokenu w wejściu · rust substr_range · rust offset of subslice within slice