Rust 使用 trait 解决类型之间的转换问题。最一般的转换会用到 Frominto 两个 trait

From 和 Into

From trait 允许一种类型定义 “怎么根据另一种类型生成自己”。
strString :

  1. let my_str = "hello";
  2. let my_string = String::from(my_str);

Into trait 就是把 From trait 倒过来而已。也就是说,如果你为你的类型实现了 From,那么同时你也就免费获得了 Into
使用 Into trait 通常要求指明要转换到的类型,因为编译器大多数时候不能推断它。

自定义转换规则:

  1. use std::convert::From;
  2. #[derive(Debug)]
  3. struct Number {
  4. value: i32,
  5. }
  6. impl From<i32> for Number {
  7. fn from(item: i32) -> Self {
  8. Number { value: item }
  9. }
  10. }
  11. fn main() {
  12. let num = Number::from(30);
  13. println!("My number is {:?}", num);
  14. let int = 5;
  15. let num: Number = int.into();
  16. println!("My number is {:?}", num);
  17. }

TryFrom 和 TryInto

TryFromTryInto trait 用于易出错的转换,所以其返回值是 Result 型。

  1. use std::convert::TryFrom;
  2. use std::convert::TryInto;
  3. #[derive(Debug, PartialEq)]
  4. struct EvenNumber(i32);
  5. impl TryFrom<i32> for EvenNumber {
  6. type Error = ();
  7. fn try_from(value: i32) -> Result<Self, Self::Error> {
  8. if value % 2 == 0 {
  9. Ok(EvenNumber(value))
  10. } else {
  11. Err(())
  12. }
  13. }
  14. }
  15. fn main() {
  16. // TryFrom
  17. assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8)));
  18. assert_eq!(EvenNumber::try_from(5), Err(()));
  19. // TryInto
  20. assert_eq!(8.try_into(), Ok(EvenNumber(8)));
  21. let result: Result<EvenNumber, ()> = 5i32.try_into();
  22. assert_eq!(result, Err(()));
  23. }

ToString 和 FromStr

把任何类型转化成 String ,只需要实现那个类型的 ToString trait。但是建议实现 fmt::Display trait,它会自动提供 ToString ,并且还可以用来打印类型。

  1. use std::string::ToString;
  2. struct Circle {
  3. radius: i32
  4. }
  5. impl ToString for Circle {
  6. fn to_string(&self) -> String {
  7. format!("Circle of radius {:?}", self.radius)
  8. }
  9. }
  10. fn main() {
  11. let circle = Circle {: 6 };
  12. println!("{}", circle.to_string());
  13. }

解析字符串

字符串转数字,标准手段是使用 parse 函数。需要提供转换到的类型,或者使用 turbo fish 语法实现。
只要对目标类型实现了FromStrtrait,就可以用 parse 把字符串转为目标类型。

  1. fn main() {
  2. let parsed: i32 = "5".parse().unwrap();
  3. let turbo_parsed = "10".parse::<i32>().unwrap();
  4. let sum = parsed + turbo_parsed;
  5. println!{"Sum: {:?}", sum};
  6. }

自定义实现:

  1. fn main() {
  2. use std::str::FromStr;
  3. #[derive(Debug)]
  4. struct Point {
  5. x: i32,
  6. y: i32,
  7. }
  8. impl FromStr for Point {
  9. type Err = ();
  10. fn from_str(s: &str) -> Result<Self, Self::Err> {
  11. let x_fromstr = s.parse::<i32>().unwrap();
  12. Ok(Point {
  13. x: x_fromstr,
  14. y: x_fromstr,
  15. })
  16. }
  17. }
  18. let p: Point = "1".parse().unwrap();
  19. // 或者使用 from_str
  20. // let p = Point::from_str("1");
  21. println!("{:?}", p);
  22. }