从`usize`向`i32`转换和从`i32`向`usize`转换有什么区别?

15

我正在制作一个函数,用于生成 n 个随机数的数组,但是我的 while 循环比较会抛出错误。

while ar.len() as i32 < size { }

投诉文件中:期望其中之一 !(+,::< 或者 > ,却发现了 {

如果我删除 as i32,它会报错 mismatch types,如果我在大小变量中添加 as usize,那么它就不会再抱怨了。


1
更好的设计可能是一开始就将size的类型设为usize - starblue
2个回答

34
当你从一个较小的类型转换为较大的类型时,你不会丢失任何数据,但是数据现在将占用更多的空间。
当你从一个较大的类型转换为较小的类型时,你可能会丢失一些数据,但是数据将占用更少的空间。
假设我有一个大小为1的盒子,可以容纳0到9的数字,还有一个大小为2的盒子,可以容纳0到99的数字。
如果我想存储数字7,则两个盒子都可以使用,但如果我使用较大的盒子,我会有剩余的空间。我可以毫不费力地将值从较小的盒子移动到较大的盒子中。
如果我想存储数字42,则只有一个盒子可以容纳该数字:较大的盒子。如果我试图将数字塞进较小的盒子中,就会丢失一些内容,通常是数字的上部分。在这种情况下,我的42将被转换为2!糟糕!
此外,有符号和无符号也起着作用;当你在有符号和无符号数字之间进行转换时,你可能会错误地解释该值,例如,像-1这样的数字变成了255!
另请参见:

在这个特定的情况下,情况会变得更加复杂。定义了一个 "指针大小整数" 的 usize,通常是机器的本地大小。在 64 位 x64 处理器上,这意味着 usize 是 64 位,在 32 位 x86 处理器上,它将是 32 位。
因此,将 usize 转换为 i32 将根据您运行的机器类型而有所不同。
您得到的错误信息是因为您尝试的代码在语法上不正确,编译器没有给出良好的错误信息。
您真正想要输入的是:
while (ar.len() as i32) < size { }

括号可以帮助正确应用优先级。
为了保险起见,我会将其转换为较大的值:
while ar.len() < size as usize { }

另请参阅:


3
只是为了澄清,因为似乎没有人指出这一点:问题在于编译器认为代码正在引入参数化类型。也就是说,类似于Vec<usize>的东西,但是它找到了{而不是>,并感到困惑。是的i32没有任何参数,但解析器不知道这一点。所有这些都发生在那种信息被知道之前。 - DK.
值得注意的是,如果由于某种原因需要将较大尺寸的变量转换为较小尺寸的变量,则可以使用 try_from,例如 while i32::try_from(ar.len()).unwrap() < size { },这将导致代码在无法转换时出错,而不是盲目地切掉多余的位。当然,您也可以通过执行比 unwrap 更复杂的操作来处理错误。 - Michael Anderson
“usize”不就是32位系统上的i32整数和64位系统上的i64整数吗?如果我错了,请纠正我。 - STEEL
1
@STEEL 是的,usize 根据目标平台会占用 16、32 或 64 位。然而,它 不是 u16 / u32 / u64 的别名,而是一种独立的类型。此外,usize 是无符号的,而 i32 / i64 则是有符号的。 - Shepmaster

6

看起来你的sizei32类型。你需要使用括号:

while (ar.len() as i32) < size { }

或将size转换为usize

while ar.len() < size as usize { }

由于len()返回一个usize,而比较运算符两边的类型需要匹配。在第一个例子中,你需要加上括号,以便<操作符不会将i32size进行比较,而是将ar.len() as i32size进行比较,这是你的意图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接