Rust类型转换知多少
Rust类型转换方式大致有三种:
- as 语法
- 实现From trait
- tryFrom trait
as 语法实现的类型转换只能用于基本类型之前都相互转换,如果基本类型转非基本类型就会编译错误。
From Trait 一般用于非基本类型的转换(比较复杂的转换),比如String::from 函数
tryFrom 和From trait 很相似,不同点就是tryFrom 返回值是result 类型(包含错误信息)
as 语法类型转换
#[cfg(test)]
mod tests {
#[test]
fn castTest() {
let a = 5_f32;
let b = a as i8;
let c = "jeebble";
let d = c as i32;// compile error
println!("{}", b);
unsafe {
println!("{}",200.0_f32.to_int_unchecked::<i8>());
}
}
}
实现From Trait
自定义Number类型,实现i32类型转Number
#[derive(Debug)]
struct Number{
value: i32,
}
impl From<i32> for Number {
fn from(value: i32) -> Number {
Number{value}
}
}
#[cfg(test)]
mod tests {
use crate::Number;
#[test]
fn fromAndToTest() {
let num =Number::from(5);
let it = 5;
let num2:Number = it.into();
println!("my number: {:?},{:?}",num,num2);
}
}
TryFrom trait
自定义一个EvenNumber struct,来实现i32转EvenNumber
use std::convert::TryFrom;
use std::convert::TryInto;
#[derive(Debug, PartialEq)]
struct EvenNumber(i32);
impl TryFrom<i32> for EvenNumber {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value % 2 == 0 {
Ok(EvenNumber(value))
} else {
Err(())
}
}
}
fn main() {
// TryFrom
assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8)));
assert_eq!(EvenNumber::try_from(5), Err(()));
// TryInto
let result: Result<EvenNumber, ()> = 8i32.try_into();
assert_eq!(result, Ok(EvenNumber(8)));
let result: Result<EvenNumber, ()> = 5i32.try_into();
assert_eq!(result, Err(()));
}
总结
本文通过三个demo来简单介绍rust类型转换,同时也介绍了三种转换方式的特点。建议针对不同的场景来使用合适的转换方式。