Rust 如何将可查看的迭代器转换回原始迭代器?

Rust 如何将可查看的迭代器转换回原始迭代器?,rust,Rust,我想实现一个跳过的算法或^字符串开头的num: fn extract_common_part(a: &str) -> Option<&str> { let mut it = a.chars(); if it.next() != Some('!') { return None; } let mut jt = it.clone().peekable(); if jt.peek() == Some(&'

我想实现一个跳过
的算法
^字符串开头的num

fn extract_common_part(a: &str) -> Option<&str> {
    let mut it = a.chars();
    if it.next() != Some('!') {
        return None;
    }
    let mut jt = it.clone().peekable();

    if jt.peek() == Some(&'^') {
        it.next();
        jt.next();
        while jt.peek().map_or(false, |v| !v.is_whitespace()) {
            it.next();
            jt.next();
        }
        it.next();
    }
    Some(it.as_str())
}

fn main() {
    assert_eq!(extract_common_part("!^4324 1234"), Some("1234"));
    assert_eq!(extract_common_part("!1234"), Some("1234"));
}
fn提取公共部分(a:&str)->选项{
设mut it=a.chars();
如果它是.next()!=Some(“!”){
不返回任何值;
}
让mut jt=it.clone().peek();
如果jt.peek(){
it.next();
jt.next();
而jt.peek().map_或(false,| v |!v.is_whitespace()){
it.next();
jt.next();
}
it.next();
}
一些(it.as_str())
}
fn main(){
断言(提取公共部分(“^4324 1234”)、一些(“^1234”);
断言(提取公共部分(“!1234”)、部分(“!1234”);
}

这是可行的,但我找不到从
peek
返回到
Chars
的方法,所以我必须推进
it
jt
迭代器。这会导致代码重复


如何从
peek
迭代器返回到相应的
Chars
迭代器,或者可能有一种更简单的方法来实现此算法?

简而言之,您不能。一般的答案是使用类似的方法来避免使用
字符
迭代器:

fn extract_common_part(a: &str) -> Option<&str> {
    let mut it = a.chars();
    if it.next() != Some('!') {
        return None;
    }

    {
        let mut jt = it.by_ref().peekable();

        if jt.peek() == Some(&'^') {
            jt.next();
            while jt.peek().map_or(false, |v| !v.is_whitespace()) {
                jt.next();
            }
        }
    }

    Some(it.as_str())
}

其他选择包括:

  • 使用一个类似板条箱的装置,这种装置是为在一根绳子上的这种增量推进而设计的
  • 直接对常规字符串进行解析,希望优化器消除冗余的边界检查
  • 使用正则表达式或其他解析库

如果您只对结果感兴趣,而没有验证:

fn extract_common_part(a: &str) -> Option<&str> {
    a.chars().rev().position(|v| v.is_whitespace() || v == '!')
        .map(|pos| &a[a.len() - pos..])    
}

fn main() {
    assert_eq!(extract_common_part("!^4324 1234"), Some("1234"));
    assert_eq!(extract_common_part("!1234"), Some("1234"));
}
fn提取公共部分(a:&str)->选项{
a、 chars().rev().position(|v | v.是_空格()| | v=='!'))
.map(| pos |&a[a.len()-pos.)
}
fn main(){
断言(提取公共部分(“^4324 1234”)、一些(“^1234”);
断言(提取公共部分(“!1234”)、部分(“!1234”);
}

5秒。甚至没有收到“新答案”通知:P@DK. 那么,我就把你答案中我没说的部分偷走。请注意,我不必写作者免责声明,这样它看起来更合法;-)免责声明:Shepmaster从
strcursor
的作者那里得到了关于
strcursor
的建议,他就是我。它应该更多地作为一个例子,而不是一个建议。@DK。呜呜呜
fn extract_common_part(a: &str) -> Option<&str> {
    a.chars().rev().position(|v| v.is_whitespace() || v == '!')
        .map(|pos| &a[a.len() - pos..])    
}

fn main() {
    assert_eq!(extract_common_part("!^4324 1234"), Some("1234"));
    assert_eq!(extract_common_part("!1234"), Some("1234"));
}