10、强制类型转换
强制类型转换
前面提到过很多次,rust不支持隐式类型转换,但是rust肯定支持显式类型转换,这一节就是学习一下rust当中显式类型转换的规则
as关键字
我们可以使用as关键字将一个类型转换为另一个类型,比如:
let a: u32 = 10;
// Cast `a` into the `u64` type
let b = a as u64;
// You can use `_` as the target type
// if it can be correctly inferred
// by the compiler. For example:
let c: u64 = a as _;
as进行类型转换的格式就是<变量名> as <转换后的类型>
,如果设置转换后的类型那一项为通配符_
那么,变量将会转换为左边要赋给的那个变量的类型
不过左边一定要有明确类型的变量定义
在这种情况下,必须给左边的变量一个明确的类型,即使rust中有默认一般整型变量为i32的规则,但是在这里是不适用的
截断
数据范围小的类型向范围大的类型转换是没有任何问题的,因为那些数据总是能包含进来
但是如果大范围向小范围转换,就会发生截断
// A number that's too big
// to fit into a `u8`
let a: u16 = 255 + 1;
let b = a as u8;
在上面的例子当中,u16类型的a转换为了u8类型的b,最后b的结果是0
从底层上讲,具体原因如下
u8类型使用一个字节进行存储,u16类型使用两个字节
当u16转换为u8时,只会保留较低的那一个字节作为u8类型的值
在这里,u16类型在内存中是这样保存的
高字节 | 低字节 |
---|---|
0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
将低字节赋给u8类型,其实也就是将0 0 0 0 0 0 0 0 赋给了u8类型,结果自然为0
事实上,rust编译器会尝试阻止它能看到的你的发生截断的类型转换
而编译器没有看到的,就放过去了
建议
根据经验,在使用as关键字进行类型转换时需要格外小心
从小类型到大类型的转换是万无一失的,但是从大类型到小类型的转换需要格外讲究,教程说后面会学习到更好的处理方式,那就后面再慢慢接触吧
局限性
as关键字可以完成各种类型转换,但是这种而理性转换并不是万能的,他只能完成一些基本类型和少数的特殊情况
对于较为复杂的复合类型,需要依赖不同的类型转换机制(fallible和infallible,这些后面会讲到,到时候再说)
Rust官方文档提供了更多的as关键字适用的情况和例子,包括IEEE754下的浮点数的转换
练习
这一节的练习文字多了一点,不过也挺简单的,就用上面学到的就可以解决
也是顺利通过了
以上就是这一节的学习内容