楼层: 首页/ 软件技术/ Rust 语言基础/ 结构体 Struct:Rust 的"类"
05

结构体 Struct:Rust 的"类"

Struct · Methods · derive

Java 用 class 把数据和方法捆一起;Rust 把这俩拆开——结构体定义数据,impl 块定义方法。没有继承,但组合 + trait 一样能干活。

三种结构体

// 1) 经典具名字段结构体:对标 Java 的 POJO struct User { username: String, age: u32, active: bool, } // 2) 元组结构体:给一组数据起个类型名,字段没名字 struct Color(i32, i32, i32); struct Point(f64, f64); // 3) 类单元结构体:没有字段,常用于实现 trait 当标记 struct AlwaysEqual; fn main() { let u = User { username: String::from("张三"), age: 30, active: true }; println!("{} 岁", u.age); let black = Color(0, 0, 0); let _b = AlwaysEqual; // 结构体更新语法:..other 把 other 里没写的字段搬过来 let u2 = User { age: 31, ..u }; // username/active 从 u 搬 println!("{}", u2.username); }

方法与关联函数:impl 块

struct Rectangle { width: u32, height: u32 } impl Rectangle { // 方法:第一个参数永远是 self,&self 借用自己(最常见) fn area(&self) -> u32 { self.width * self.height } // &mut self:可变借用,能改自己;self:拿走所有权 fn scale(&mut self, k: u32) { self.width *= k; } // 关联函数:没有 self 参数,相当于 Java 的静态方法,用 :: 调用 fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size } } } fn main() { let mut r = Rectangle { width: 3, height: 4 }; println!("面积 {}", r.area()); // 方法用点号调用 r.scale(2); let s = Rectangle::square(5); // 关联函数用 :: 调用 println!("{} {}", r.width, s.area()); }
$ cargo run 面积 12 6 25

派生属性 derive:编译器帮你实现常见 trait

// 一行 derive,自动实现一堆常用 trait #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] struct Point { x: i32, y: i32 } fn main() { let p = Point { x: 1, y: 2 }; println!("{:?}", p); // Debug 派生后才能 {:?} 打印 let p2 = Point::default(); // Default 派生后有默认值 println!("{}", p == Point{x:1,y:2}); // PartialEq 派生后才能 == }
$ cargo run Point { x: 1, y: 2 } true

论字段可见性 pub

结构体的字段默认私有,别的模块看不见。想暴露就在字段前加 pub。方法同理——不过方法默认是"该类型自己的",对外暴露需要 pub fn。这跟 Java 的 private/public 一个道理。