怎么使用Rust语言的类型转换
本篇内容介绍了"怎么使用Rust语言的类型转换"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
什么是类型转换?
类型转换,是调用函数时,根据函数要求的参数签名类型A,将我们手中的类型B转换为类型A的过程,而且不能改变B的所有权。一般的函数调用都要求我们传递引用,很少需要直接传递所有权的。
很多语言提供了向上转型和向下转型,例如Java和C++等,如此使用(B)A,即可将B强制转换成A。但是强转是有一定的风险的,Java里强转失败会抛出CastException,而在C++里有时候不抛异常,必须使用更高版本的cast系列函数去转换,才可以保证转换失败时给出异常,避免产生内存安全的问题。
Rust虽然是各种安全风险可控的编程语言,但是也有一些是需要开发人员事先了解的,比如整型之间强转的结果并不尽如人意。
as操作符
1、在编码过程中,使用最多的转换,要数整型的强制转换了。
我们往往会遇见这样的类型需求usize,这个类型一般代指长度或者数组索引,我们只有i32之类的整型变量是不能直接透传进去的,必须使用as关键字作强制转换后,才可以通过编译器的检测。
但是,这里会发生一些意想不到的事情,比如类型截断。
什么是类型截断,即一个值范围较大的变量A转换为值范围较小的变量B,如果超出范围,则将A减去B的区间长度。
例如,128超出了i8类型的范围(-128,127),强转之后的值等于128-256=-128。
2、在学习Trait的时候,我们发现一个问题,类型A可以实现很多Trait,有些Trait存在函数签名相同的情况,但是内部实现却不相同,如果使用A为主题去调用的话,编译器无法判断应该调用哪个函数,所以必须将A向上强转为特定的Trait,以告知编译器如何做出判断。
例如,B和C是有同名含函数name()的Trait,A分别实现了他们,当A想要调用B的name()的时候,需要显示转换,避免歧义,如::name()。
3、as还可以在父类型与子类型之间相互转换,比如&’static str和&'a str。'static生命周期是整个进程存活期间有效的,而'a的生命周期较短,我们称&'static是&'a的子类型,使用'static:'a来表示。as可以将父子类型自由转换,如&'static str as &'a str,这种做法的意义是为了满足某些函数对生命周期的要求。
From和Into
这2个Trait定义在标准库的convert模块中,其实他们做的是同一件事情,不要被From和Into绕晕掉。
举个形象的比喻,我吃饭,和饭被我吃,是一回事。只要我在吃饭,那么饭肯定正在被我吃,是一个道理。
Rust还为此定义了一个定理:如果类型A实现了From,则B类型实例调用into方法就可以转换为类型A。
例如,我们常见的字符串String类型实现了From(&str),那么&str就可以into()为String。
大多数情况下,我们只需要实现From这个Trait即可,Rust为所有实现From的自动实现了反方向的Into。
From和Into也不是完全没有异常发生的,当我们不确定转换的结果是我们想要的时候,可以实现TryFrom和TryInto这两个Trait,以捕获可能发生的错误信息。
AsRef和AsMut
AsRef和AsMut可以将类型分别转换为不可变引用和可变引用。这两个Trait对我们实现可扩展的函数是非常有帮助的。
比如,我们想设计一个允许传入&String和&str都可以的函数,那么像下图中的test函数那样做:
如果我们自己定义一个类型,最好能实现AsRef这个Trait,它会给我们带来很多意想不到的实惠。
FromStr
Rust内置了很多帮助我们类型转换的实现,字符串和其他类型之间的转换,都会默认实现FromStr这个Trait。
如果想把一个字符串转换为整型,可以使用parse函数,它会根据返回值类型自动解析字符串,以得到正确类型的返回值。
整型转换为字符串,就不用多说了,直接format宏格式化即可。
"怎么使用Rust语言的类型转换"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!