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类型繁多,但是类型的统一风格做的还是不错的,通过各种Trait让类型与类型之间的逻辑脉络有了统一的可能性,不得不说,理解了类型转换之后,在设计代码的时候可以更加的优雅,兼容性更好。

作为十几年的程序员来说,语言之间都是有共性的,纵观所有的编程语言,Rust在类型设计上并不是那么优雅的,特别是泛型与生命周期结合起来以后,让程序员对代码的直观理解降低到了一个可怕的程度。

既然选择学习Rust,就要有相关的觉悟,学习曲线陡峭才可以拉开与懒惰者的差距。

学会努力,比努力本身更重要。

 

责任编辑:未丽燕 来源: 今日头条
相关推荐

2022-12-06 17:30:04

2024-07-31 09:28:56

2024-10-18 11:48:00

2017-11-27 12:24:02

命令行代码指令

2021-09-03 06:46:34

MyBatis缓存后端

2024-08-12 15:44:06

2021-12-26 18:30:56

嵌入式ARM链接

2016-12-02 20:43:28

Android

2017-03-07 09:49:18

存储

2020-10-09 10:45:22

语言代码数组

2021-07-29 18:46:52

可视化类型图形化

2023-10-16 08:55:43

Redisson分布式

2022-07-18 07:58:46

Spring工具工具类

2017-09-27 14:57:44

IOS 11Siri苹果

2016-12-26 09:50:15

2023-04-10 07:40:36

GraphQLRest通信模式

2017-11-06 19:09:45

在线抓娃娃机

2022-07-19 08:04:04

HTTP应用层协议

2023-06-03 00:05:18

TypeScriptJSDoc扫描器

2024-11-13 09:22:40

点赞
收藏

51CTO技术栈公众号