29.rust类型转换.rs
/*
1.基本类型可以通过显示类型转换机制(as)来实现相互之间的转换。
2.Rust通过使用trait来处理定制类型(enum、struct)之间的类型转换。
3.通用的类型转换一般使用的trait为From和To。Rust孤儿原则:
在声明trait和impl trait的时候,Rust规定了一个Orphan Rule(孤儿规则):impl块要么与trait的声明在同一个的crate中,要么与类型的声明在同一个crate中。
也就是说,不能在一个crate中,针对一个外部的类型,实现一个外部的trait。
*/fn test_1() {/*as 运算符有点像 C 中的强制类型转换,区别在于,它只能用于原始类型(i32 、i64 、f32 、f64 、 u8 、 u32 、 char 等类型),并且它是安全的*///在 Rust 中,不同的数值类型是不能进行隐式转换的//let b: i64 = 1i64; 会出现编译错误,提示无法进行类型转换。let b: i64 = 1i32 as i64;let c:i32 = 123.456f32 as i32;//为什么它是安全的?像这种不安全的转换编译不过//let b = 1i32 as char;Rust 会拒绝转换,这也避免了运行时错误。
}fn test_2() {/*From和Into trait是成对的存在,它表示了一个类型A通过怎样的处理能变成类型B,通常我们只需要为类型B实现From trait的from(以类型A为参数)方法,就自动获得了由类型A的into方法转换成类型B。*/use std::convert::From;//use std::convert::Into;#[derive(Debug)]struct Square {width: i32,height: i32,}impl From<i32> for Square {fn from(size: i32) -> Self {Square {width: size,height: size,}}}impl Square {fn area(&self) -> i32 {self.width * self.height}}/*通过上面的示例,我们很容看到,要将类型A转换成类型B,可以为类型B实现From trait的from(A)方法,将类型A作为参数实现转换;同时在实现了类型B的From trait后,类型A可以直接调用into()方法转换成类型B。总结下来可以用以下伪代码作为示意:let b = B::from(A);let b:B = A.into();为方便记忆,可以简化成一句:translate A to B,impl B how to from A.*/let s = Square::from(10_i32);println!("s is {:?},area is {}", s, s.area());let a: Square = 20.into(); //这里的Square类型需要显示标注println!("a is {:?}", a);
}fn test_3() {/*TryFrom与TryInto与From和Into类似,TryFrom和TryInto是类型之间转换的通用的trait。与From和Into不同的是,TryFrom和TryInto被用来处理可能出现失败的转换,因而,他们返回的是Result类型。*/use std::convert::TryFrom;use std::convert::TryInto;#[derive(Debug, PartialEq)]struct DOT {number: u128,}impl TryFrom<u128> for DOT {type Error = ();fn try_from(size: u128) -> Result<DOT, Self::Error> {Ok(DOT {number: size,})}}impl TryFrom<DOT> for u128 {type Error = ();fn try_from(dot: DOT) -> Result<u128, Self::Error> {Ok(dot.number)}} let d1 = DOT{number:100}; let d2 = DOT{number:100};let t1 = DOT::try_from(8u128);let t2 = u128::try_from(d2); let t3:Result<u128,_> = DOT::try_into(d1);//自己结构体是DOT,try_into把自己向某种类型转换,你不告诉我类型我怎么知道向什么方向转?所以必须声明返回类型let t4:Result<DOT,_> = u128::try_into(12u128);//同上let d1 = DOT{number:100}; let d2 = DOT{number:100};let t1:Result<DOT,_> = TryFrom::<u128>::try_from(8u128);let t2:Result<u128,_> = TryFrom::<DOT>::try_from(d1);let t3 = TryInto::<u128>::try_into(d2);let t4 = TryInto::<DOT>::try_into(8u128);
}fn test_4() {/*转换为字符串为了把一个类型转为String类型,我们只要实现traitToString就可以了。然而,我们并不会直接的这样做,我们应该实现traitfmt::Display,这个trait会自动提供ToString,而且会可以打印这个类型。*/use std::fmt;struct Circle {radius: i32,}impl fmt::Display for Circle {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {write!(f, "Circle of radius {}", self.radius)}}let circle = Circle { radius: 6 };println!("{}", circle.to_string());
}fn test_5() {/*解析一个字符串一个最常见的类型转换是把一个字符串转换为一个数字。实现这个功能的常用方法是使用parse方法,并且使用rust类型类型推断或者使用turbofish语法来指定类型。我们会在如下的示例代码中来使用这两个方法。只要为该类型实现了FromStr,就可以实现从字符串到指定类型的转换。标准库中的很多类型都实现了该trait。如果要在用户定义的类型的上获得该功能,只要实现FromStr就可以了。*/// let parsed: i32 = "5".parse().unwarp();// let turbo_parsed = "10".parse::<i32>().unwarp();// let sum = parsed + turbo_parsed;// println!("Sum: {:?}", sum);
}//解引用强制多态
fn test_6() {fn print(message: &str) {println!("{}", message);}let message: String = "message".to_string();print(&message);/*print 的形参是 &str 类型,然而在 main 中,我传递却是一个 &String 类型的实参。明显,这两个类型不相同!!Rust 为什么会通过这样的代码呢?没错,这就是 Rust 的 解引用强制多态。首先,需要了解一个 Deref Trait 。#[lang = "deref"]pub trait Deref {type Target: ?Sized;#[must_use]fn deref(&self) -> &Self::Target;}deref 方法返回一个 &Target 类型的引用。回忆一下 Rust 中的解引用语法,当 ref 是一个引用或智能指针时,我们可以使用 *ref 的方式解引用。这是类似一个语法糖,对于 *ref 这种写法,写全应该时 *(ref.deref()) 。回想 Box<T> 的使用,Box<T> 实现了 Deref ,它的 deref 方法返回 &T 的引用,然后使用解引用运算符 * ,我们顺利拿到一个 T 类型的数据。也就是,你可以通过实现 Deref 以重载解引用运算符。Deref 和这节的内容有什么关系呢?当 T 实现了 Deref<Target=U> 时,对于需要 &U 的地方,你可以提供一个 &T 类型的数据,Rust会为你自动调用 deref 方法,而这个过程可以重复多次。比如,我自定义类型 P 实现了 Deref<Target=String> ,那么可以把 &P 类型变量传递给一个 &str 类型变量。&P -> &String -> &str ,伪代码: &P.deref().deref() 。回到这节开头的例子,print(&message) 相当于 print((&message).deref()) ,正好是一个 &str 类型。*/
}fn main() {test_1();test_2();test_3();test_4();test_5();test_6();
}
29.rust类型转换.rs相关推荐
- Rust学习资料大全
2021年接触了区块链,接触了波卡,接触了rust,接触了一个全新的世界,愿自己可以有一个好的发展,加油!!!rust语言是一门新兴起的编程语言,作为一个编程爱好者很想把他学精学透.但是一门编程语言没 ...
- rust做嵌入式开发_Rust 嵌入式开发 STM32 amp; RISC-V
Rust 嵌入式开发 STM32 & RISC-V 发布于 2020-04-03 11:07:06 本帖最后由 wuhanstudio 于 2020-4-3 11:58 编辑 更新地址: [m ...
- Rust 1.33.0 发布,OSC 上堪称“零差评”的编程语言
Rust 最新稳定版 1.33.0 已发布,如果已安装过 Rust,可通过以下方式进行升级: $ rustup update stable 如果从未安装过 Rust,请参考该页面的说明进行安装:htt ...
- RUST 环境 UDP UART CANFD
文章目录 测试环境 RUST 安装 VSCode 配置 新工程 args 命令行参数传入 多文件 mod 和 include 多bin 与 workspace println thread 多生产-单 ...
- 【erlang】吃螃蟹 rust 开发 erlang nif 的正确方式 rustler
用rust编写erlang的nif方案,以下几个star比较高 Rustler ( https://github.com/hansihe/rustler ) 这个比较火,但是没有关于如何在 Erlan ...
- Rust actix aiohttp_【Rust架构】Rust web框架比较
目录 服务器框架 过时的服务器框架 客户框架 过时的客户框架 前端框架(WASM) 补充库 WebSocket 模板 对照 高级框架 低级框架 前端框架 中间件和插件 Websocket库 资源 博客 ...
- 20144306《网络对抗》Web基础
1 实验内容 Web前端HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt:理解JavaScript ...
- 计算机系统导论——读书笔记——第二章 信息的表示和处理(持续更新)
第二章 信息的表示和处理 2.1 信息存储 2.1.1 十六进制 2.1.2 字数据大小 2.1.3 寻址和字节顺序 1.地址:对象所使用的字节中最小的地址 2.大端法:最高有效字节在前 小端法:最低 ...
- hql调用mysql存储过程_hibernate调用mysql存储过程
在mysql中创建两个存储过程,如下: 1.根据id查找某条数据: 1 CREATE PROCEDURE `findEmpById`(IN id INTEGER(11))2 begin3 s ...
最新文章
- Xcode clang-omp openmp开发
- AI研发工程师成长指南
- 解读中国互联网:局部领先、快进的数字化发展
- 检测高CPU线程定位shell脚本
- spring cloud 调用接口间歇性返回http 500 - Internal Server Error的错误
- 数据库每日一题 2020.05.25
- 【Git基础笔记】常用命令
- SQL Server 2005 如何自动备份数据库
- python 初级笔记
- MySQL数据库通过cmd窗口导入sql文件
- 小米平板2刷android,小米平板2怎么刷回MIUI 小米平板2刷回MIUI教程
- 李小铭计算机专业应聘书作文,应聘申请书英语作文
- 香橙派基于翔云的人脸识别
- 九、51单片机之直流电机驱动
- Word排版计算机类科研论文的格式保证
- 一度智信|拼多多客服售后须知
- BZOJ3827[Poi2014] Around the world
- PET(聚对苯二甲酸乙二醇酯)——百度百科
- 计算机的领域分类网上购物属于,大学本科计算机专业网上购物系统设计毕业论文.doc...
- 全球及中国建筑化学品行业需求态势与投资策略建议报告