Rust 通过 Structs 来定义一些特定结构。

定义结构

可以定义成类似于 JS 中的 Object 。

  1. #[derive(Debug)]
  2. struct User {
  3. name: String,
  4. age: u8,
  5. description: String,
  6. }
  7. fn build_user() -> User {
  8. User {
  9. name: String::from("axes"),
  10. age: 10,
  11. description: String::from("cool guy"),
  12. }
  13. }
  14. fn main() {
  15. let user = build_user();
  16. println!("{:?}, {}: {}", user, user.name, user.description);
  17. }

使用 {:?} + #[derive(Debug)] 声明是为了能让 struct 能够正确打印出来。如果使用 {:#?} 打印的效果就类似于 JS 中的 JSON.stringify(xxx, null, 2) ,是带缩进的。

定义 tuple

也可以定义成 tuple struct

  1. struct Color(i32, i32, i32);
  2. struct Point(i32, i32, i32);
  3. let black = Color(0, 0, 0);
  4. let origin = Point(0, 0, 0);

定义方法

可以针对 struct 定义方法。

  1. struct Retangle {
  2. width: u32,
  3. height: u32,
  4. }
  5. impl Retangle {
  6. fn area(&self) -> u32 {
  7. self.width * self.height
  8. }
  9. fn can_hold(&self, other: &Retangle) -> bool {
  10. self.width > other.width && self.height > other.height
  11. }
  12. fn new(width: u32, height: u32) -> Retangle {
  13. Retangle {
  14. width: width,
  15. height: height,
  16. }
  17. }
  18. }
  19. fn main() {
  20. let rt = Retangle {
  21. width: 100,
  22. height: 30,
  23. };
  24. println!("{}", rt.area());
  25. let rt2 = Retangle::new(10, 20);
  26. println!("{}", rt2.area());
  27. println!("{}", rt.can_hold(&rt2));
  28. }

可以通过 impl这个关键词定义方法,定义的方法如果首个入参是 &self 那么该方法会认为是 struct 这个实例的方法,否则会认为是 static method ,即与实例无关的。

两种调用的语法不同,前者是用 . 后者是用 :: ,就像平时习惯用的 String::from("xxx"),这种一般用于上面代码中那样来创建 struct 。

在 c/c++ 中,调用 struct 实例的方法会区分是通过实例调还是通过指针调,如果是实例调是 xxx.xx ,如果通过指针调是 xxx->xx,但是在 rust 中会自动识别当前是实例还是指针,自动选择合适的方式来调用,也就是上面的代码中 &rt.area()rt.area() 是等价的。