【Rust深入浅出-4】类型转换
第一章 Hello World!
第二章 变量和基本数据类型
第三章 运算符
第四章 类型转换
前言
Rust深入浅出教程第四章《类型转换》
本章节将介绍基本数据类型之间的转换
本文用到了一些match等后期知识,不理解不影响阅读
as操作词
用法:变量 as Type
支持as的类型转换是固定的,使用as时我们必须遵守这些规则
类a | 类b | a as b |
---|---|---|
Integer/float | Integer/float | 数字转换(Numeric cast) |
enum | Integer | 枚举转换(Enum cast) |
bool/char | Integer | 基元整数转换(Primitive to integer cast) |
u8 | char | u8 to char cast |
*T | *V where V: Sized * | Pointer to pointer cast |
*T where T: Sized | Integer type | Pointer to address cast |
Integer type | *V where V: Sized | Address to pointer cast |
&m₁ T | *m₂ T ** | Reference to pointer cast |
&m₁ [T; n] | *m₂ T ** | Array to pointer cast |
Function item | Function pointer | Function item to function pointer cast |
Function item | *V where V: Sized | Function item to pointer cast |
Function item | Integer | Function item to address cast |
Function pointer | *V where V: Sized | Function pointer to pointer cast |
Function pointer | Integer | Function pointer to address cast |
Closure *** | Function pointer | Closure to function pointer cast |
示例代码
let a: f64 = 1.9;
println!("[1] a: {}",a as i32); //取整,没有四舍五入
let a: i32 = 1;
let a = a as f64;
println!("[2] a: {}",a); //类型变了,但小数位没有补上
let a: u8 = 1; //只有u8能转成字符
let a: char = a as char;
let a: &'static str = "rust";
let a = a as &str;
println!("[3] a: {}",a);
let a: String = String::from("evan");
let a = &a as &str;
println!("[4] a: {}",a);
from & into
From和Into是用于类型转换的接口,当一个类型继承并实现了向某零一类型转换的From和Into,我们就可以调用From和Into转换类型,我们之前学过的String::from就是这个
示例代码
let a: i32 = 200;
// let a: u32 = u32::from(a); //未实现,报错
let a: f64 = f64::from(a);
println!("[1] a: {}", a);
try_into & try_from
try_into和try_from的实质是调用了一个From和Into的二次封装,局限性和From&Into相同
只要被赋予的新变量的类型是显式或者可推测的,就可以调用try_into进行转换,并且以Result的形式返回,程序员根据Result进行正确与错误分支处理
示例代码:
let a: u64 = 100;
let b: u16 = a.try_into().unwrap();
println!("[1] b: {}",b);
let a: u16 = 1000;
let b: u8 = match a.try_into() {
Ok(v) => {
println!("[2] u16->u8: Ok");
v
},
Err(_) => {
println!("[2] u16->u8: Err");
0
}
};
/*
the following other types implement trait `From<T>`:
<f32 as From<i16>>
<f32 as From<i8>>
<f32 as From<u16>>
<f32 as From<u8>>
<f64 as From<f32>>
<f64 as From<i16>>
<f64 as From<i32>>
<f64 as From<i8>>
*/
let a: f32 = 1.111;
let b: f64 = a.try_into().unwrap();
println!("[3] a: {}",a);
println!("[3] b: {}",b);
/*
the following other types implement trait `From<T>`:
<String as From<&String>>
<String as From<&mut str>>
<String as From<&str>>
<String as From<Box<str>>>
<String as From<Cow<'a, str>>>
<String as From<char>>
*/
let a: &str = "rust";
let b: String = a.try_into().unwrap();
println!("[4] b: {}",b);
其它
业务代码中可能最长用到的类转就是字符串转数字了
而以上方法均不支持字符串转数字,因此String本身实现了一个转字符串的方法parse()
示例代码
// 简化版
let a: u32 = "200".parse().unwrap();
println!("[1] a: {}",a);
// 处理错误
let a: i32 = match "2X00".parse() {
Ok(f) => f,
Err(err) => {
println!("{}",err.to_string());
-1
},
};
println!("[2] a: {}",a);
输出
[1] a: 200
invalid digit found in string
[2] a: -1
总结
本掌介绍了as, From&Into, try_from&try_into 和 parse 四种基本类型转换方法,as是子集类型向父集类型兼容,需要注意溢出问题,try_from&try_into 和 From&Into 一脉相承,简化了书写格式,parse则用于常见的字符串转数字
下一章 拓展数据类型