在while循环中重新绑定可变变量是否有效?我无法使用以下简单的解析器代码。我的目的是用逐渐缩短的切片替换newslice绑定,因为我将字符从数组的前面复制出来。
/// 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
答案 0 :(得分:1)
重新绑定这样的变量非常好。一般规则很简单:如果编译器没有抱怨,那就没关系。
这是一个非常简单的错误:你的切片终点是不正确的。
slice
产生间隔[开始,结束] - 半开放范围,未关闭。因此,当您希望删除第一个字符时,您应该编写newslice.slice(1, newslice.len())
,而不是newslice.slice(1, newslice.len() - 1)
。你也可以写newslice.slice_from(1)
。
答案 1 :(得分:1)
As Chris Morgan mentioned,您对slice
的调用传递了end
参数的错误值。 newslice.slice_from(1)
会产生正确的切片。
is_digit
测试错误的字节值。您打算写0x30
等代替30
。
您在错误的值上调用str::from_utf8
。您打算在n.as_slice()
而不是newslice
上调用它。