Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/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 为什么对usize数字进行减号操作可以';不要消极什么';处理这个问题的惯用方法是什么?_Rust - Fatal编程技术网

Rust 为什么对usize数字进行减号操作可以';不要消极什么';处理这个问题的惯用方法是什么?

Rust 为什么对usize数字进行减号操作可以';不要消极什么';处理这个问题的惯用方法是什么?,rust,Rust,s和t是向量。如果我们这样做: t.len() - s.len() 如果减法结果为负(因为两种类型都是usize) 但是,如果我们没有意识到这两种类型都是usize,并且我们期望结果可能是负数,那么它可能会导致一个棘手的错误(我自己遇到过,并且只在运行时在边缘情况下发现)。为了修复错误,我将它们转换为: t.len() as i32 - s.len() as i32 我的问题是: 为什么Rust不将usize减法转换为有符号类型 在编译时早期捕获此类bug的惯用方法是什么 我不知道惯用的方

s
t
是向量。如果我们这样做:

t.len() - s.len()
如果减法结果为负(因为两种类型都是
usize

但是,如果我们没有意识到这两种类型都是
usize
,并且我们期望结果可能是负数,那么它可能会导致一个棘手的错误(我自己遇到过,并且只在运行时在边缘情况下发现)。为了修复错误,我将它们转换为:

t.len() as i32 - s.len() as i32
我的问题是:

  • 为什么Rust不将
    usize
    减法转换为有符号类型
  • 在编译时早期捕获此类bug的惯用方法是什么

我不知道
惯用的方式,但我相信或可能是一个好的解决方案

所以最后它可能看起来像:

match t.len().checked_sub(s.len()) {
    None => println!("Error"),
    Some(diff) => println!("Difference is {}", diff),
}
为了修复错误,我将它们转换为:

t.len() as i32 - s.len() as i32
根据平台的不同,
usize
可以是64b,
isize
是为了扩散usize而存在的,尽管它仍然只有
usize
的一半正范围,但将其转换为
i128
将提供更大的确定性(至少在我们获得具有128b usize的平台之前)但在32b平台上可能效率很低,因为它们可能没有128b操作的硬件支持,而是用软件实现

为什么Rust不将usize减法转换为有符号类型

因为数字类型上的算术运算是使用宏以相同的输入和输出批量实现的

您建议的选项也会有自己的问题,例如,
usize::MAX-1
会返回垃圾

在编译时早期捕获此类bug的惯用方法是什么

数值类型具有显式溢出行为的方法:失败(
已选中)
、换行(
换行)
)或饱和(
饱和)
)。有一种包装类型用于包装操作,因为这在某些上下文中非常常见(例如加密),但我认为没有一种包装类型用于检查操作


没有真正惯用的方法来处理这个问题,因为这是一个逐案的问题,而且这一次,默认情况下,这种故障被判断为太不方便,太容易出现。

关于您的第一个问题“为什么Rust不转换…?”:因为Rust通常不会进行自动类型转换。自动类型转换是其他编程语言中错误的来源;Rust要求您显式地执行这些操作,以便了解转换,这有助于避免bug。正如@Jesper所说,这不是bug,而是特性。如果要避免出现
恐慌
,一个选项是使用,它返回一个选项。例如,
t.len()。选中子项(s.len())。如果
s
的长度大于
t
,因此无法减去,则展开或(0)