Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 恐慌于';尝试使用溢出进行减法';当通过列表向后循环时_Rust_Integer Overflow_Integer Arithmetic - Fatal编程技术网

Rust 恐慌于';尝试使用溢出进行减法';当通过列表向后循环时

Rust 恐慌于';尝试使用溢出进行减法';当通过列表向后循环时,rust,integer-overflow,integer-arithmetic,Rust,Integer Overflow,Integer Arithmetic,我正在为一个向前或向后移动索引的列表编写一个循环方法。以下代码用于向后循环: (i-1)%list_length 在这种情况下,i的类型为usize,这意味着它是无符号的。如果i等于0,则会导致“尝试使用溢出进行减法”错误。我尝试使用正确的铸造方法来解决此问题: ((i as isize)-1)%(list_length as isize)) as usize 这将导致整数溢出 我理解错误发生的原因,目前我已经通过检查索引是否等于0解决了问题,但我想知道是否有办法通过将变量强制转换为正确的类

我正在为一个向前或向后移动索引的列表编写一个循环方法。以下代码用于向后循环:

(i-1)%list_length
在这种情况下,
i
的类型为
usize
,这意味着它是无符号的。如果
i
等于0,则会导致“尝试使用溢出进行减法”错误。我尝试使用正确的铸造方法来解决此问题:

((i as isize)-1)%(list_length as isize)) as usize
这将导致整数溢出


我理解错误发生的原因,目前我已经通过检查索引是否等于0解决了问题,但我想知道是否有办法通过将变量强制转换为正确的类型来解决问题。

如果您的代码可能有溢出操作,我建议使用。当您允许时,您无需担心投出或溢出恐慌:

use std::num::Wrapping;

let zero = Wrapping(0u32);
let one = Wrapping(1u32);

assert_eq!(std::u32::MAX, (zero - one).0);
因此,您不希望在整数级别使用包装语义:

fn main() {
    let idx: usize = 0;
    let len = 10;

    let next_idx = idx.wrapping_sub(1) % len;
    println!("{}", next_idx) // Prints 5!!!
}
相反,您希望使用模逻辑来概括:

let next_idx = (idx + len - 1) % len;
只有当
len
+
idx
小于类型的最大值时,这才有效-使用
u8
而不是
usize
时,这更容易看到;只需将
idx
设置为200,将
len
设置为250即可

如果不能保证这两个值的总和总是小于最大值,我可能会使用“checked”运算族。这与您已经提到的条件检查的级别相同,但整齐地捆绑在一行中:

let next_idx = idx.checked_sub(1).unwrap_or(len - 1);

旁白:我认为你根本不想那样做<代码>(-1%10)是
-1
,而不是
9
-1isize as usize
18446744073709551615
(在64位体系结构上)。好的,我不知道。我原以为它的工作方式与中所述相同,但现在我看到它的实现方式与中所述相同。那就清楚了!还有一个包装算法。