Closed
Description
impl<'a> Chars<'a> {
fn remaining(&self) -> 'a &str { self.string }
}
This is quite useful when scanning strings, especially when more flexibility is needed. For example, the following example uses slice_from
which is not always safe as it uses byte offsets (but using char offsets would be O(n) and I want to avoid it!).
// This code basically parses a markdown horizontal rule.
let item: char = '*';
// Counts the number of items
let mut cnt: uint = 0;
// Counts the consumed spaces (and the final NL)
let mut spc: uint = 0;
for ch in string.chars() {
if ch == item { cnt += 1; }
else if ch == '\n' { spc += 1; break; }
else if ch == ' ' { spc += 1; }
else { return None; }
}
if cnt >= 3 {
// return sucess and the remaining string to continue parsing!
Some(string.slice_from(cnt + spc))
} else {
None
}
Instead when something like remaining()
would exist, the code could be rewritten as:
let item = '*';
// Counts the number of items
let mut cnt: uint = 0;
let iter = string.chars();
for ch in iter {
if ch == item { cnt += 1; }
else if ch == '\n' { break; }
else if ch == ' ' {}
else { return None; }
}
if cnt >= 3 {
Some(iter.remaining())
} else {
None
}
This comes in very useful and is also more efficient! Iterators are not always enough, so that's why I do not want to pass iterators around and instead work on string slices.
Metadata
Metadata
Assignees
Labels
No labels