索引检出越界时分配返回值

时间:2017-07-02 19:36:43

标签: rust

在伪代码中,我尝试以下方法:

a = (*p++) ? (*p++) : 0 

其中for i in len(array): try: a = array[i-1] except(out_of_bounds_error): a = false 只是由布尔组成。

在本书(第9.2章)中,它说你可以检查函数是否返回结果:

array

告诉我let a: u32 = array[i-1] 确实是一个布尔。如果没有a类型,如何在运行时处理不可避免的(和期望的)Result错误?

1 个答案:

答案 0 :(得分:4)

attempt to subtract with overflow时计算i - 1时出现错误i == 0。数组索引必须是usize类型,这是无符号类型,无符号类型不能表示0 - 1将产生的负数。在调试版本中,编译器会生成引发此错误的代码,但在发布版本中,编译器会生成只会计算“错误”值的代码(在这种情况下,恰好是usize::max_value())。 / p>

您可以通过执行选中的减法来避免调试版本和发布版本中的此错误。 checked_sub会返回Option:如果减法成功,您将获得Some;如果失败,则会None。然后,您可以在Option上使用map_or仅在减法生成有效索引时才读取数组。

fn main() {
    let a = vec![true; 10];

    for i in 0..a.len() {
        let b = i.checked_sub(1).map_or(false, |j| a[j]);
        println!("b: {}", b);
    }
}

数组(或更确切地说,切片)也有get方法,如果索引超出界限,则返回Option,而不是恐慌。如果我们在索引中添加一个,而不是减去一个,我们可以这样做:

fn main() {
    let a = vec![true; 10];

    for i in 0..a.len() {
        let b = i.checked_add(1).and_then(|j| a.get(j).cloned()).unwrap_or(false);
        println!("b: {}", b);
    }
}

这一次,我们使用and_then将产生Option的操作与另一个产生Option的操作链接起来,我们正在使用unwrap_or获取Option的值或默认值None