【问题标题】:Is it valid to rebind a variable in a while loop?在while循环中重新绑定变量是否有效?
【发布时间】:2014-12-01 20:34:12
【问题描述】:

在 while 循环中重新绑定可变变量是否有效?我无法让以下简单的解析器代码工作。我的意图是在将字符从数组前面复制出来时,用逐渐变短的切片替换新闻切片绑定。

/// Test if a char is an ASCII digit
fn is_digit(c:u8) -> bool {
    match c {
        30|31|32|33|34|35|36|37|38|39 => true,
        _ => false
    }
}

/// Parse an integer from the front of an ascii string,
/// and return it along with the remainder of the string
fn parse_int(s:&[u8]) -> (u32, &[u8]) {
    use std::str;
    assert!(s.len()>0);
    let mut newslice = s; // bytecopy of the fat pointer?
    let mut n:Vec<u8> = vec![];

    // Pull the leading digits into a separate array
    while newslice.len()>0 && is_digit(newslice[0])
    {
        n.push(newslice[0]);
        newslice = newslice.slice(1,newslice.len()-1);
        //newslice = newslice[1..];
    }

    match from_str::<u32>(str::from_utf8(newslice).unwrap()) {
        Some(i) => (i,newslice),
        None => panic!("Could not convert string to int.  Corrupted pgm file?"),
    }
}

fn main(){
            let s:&[u8] = b"12345";
            assert!(s.len()==5);
            let (i,newslice) = parse_int(s);
            assert!(i==12345);
            println!("length of returned slice: {}",newslice.len());
            assert!(newslice.len()==0);
}

parse_int 未能返回比我传入的切片更小的切片:

length of returned slice: 5
task '<main>' panicked at 'assertion failed: newslice.len() == 0', <anon>:37
playpen: application terminated with error code 101

Run this code in the rust playpen

【问题讨论】:

  • is_digit 可以写成c &gt;= b'0' &amp;&amp; c &lt;= b'9',顺便说一句。
  • 对,我希望这整个代码块如果还没有被标准库淘汰的话。我正在学习,并避免像瘟疫这样的外部依赖,直到 1.0。

标签: while-loop rust slice


【解决方案1】:
  1. As Chris Morgan mentioned,您对slice 的调用传递了错误的end 参数值。 newslice.slice_from(1) 产生正确的切片。

  2. is_digit 测试错误的字节值。你的意思是写0x30等而不是30

  3. 您调用 str::from_utf8 的值有误。你的意思是在n.as_slice()而不是newslice上调用它。

【讨论】:

    【解决方案2】:

    像这样重新绑定变量是非常好的。一般规则很简单:如果编译器没有抱怨,那就没关系。

    这是您犯的一个非常简单的错误:您的切片端点不正确。

    slice 产生区间 [start, end)——一个半开的范围,而不是封闭的。因此,当您只想删除第一个字符时,您应该写newslice.slice(1, newslice.len()),而不是newslice.slice(1, newslice.len() - 1)。你也可以写newslice.slice_from(1)

    【讨论】:

    • 感谢您发现 Chris,但进行该更改似乎不会影响行为...is.gd/rBIMNF
    • 所以要么我有其他一些新手错误,要么编译器没有处理我从 match 语句内部构造的匿名元组?
    • 谢谢!但是哦,伙计,这三个错误是否令人尴尬。这些都是在重构过程中出现的,以使代码通过编译器,但仍然......我认为我应该删除这个问题吗?还是留下它以防有人搜索恰好是正确的代码?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多