impl ... for ...
结构在 Rust 中有两种主要用途:
-
为类型定义方法
- 语法:
impl 类型名 { ... }
- 用于为结构体、枚举等类型定义关联函数和实例方法
- 示例中为
Rectangle
结构体定义了new
(关联函数)、area
和scale
(实例方法)
- 语法:
-
为类型实现特质
- 语法:
impl 特质名 for 类型名 { ... }
- 用于为类型实现特定的特质,实现接口定义的方法
- 示例中为
Circle
实现了Shape
特质,为i32
、String
和bool
实现了Printable
特质
- 语法:
关键概念解析
-
关联函数 :在
impl
块中定义的没有self
参数的函数,通过类型名::函数名()
调用(如Rectangle::new()
) -
实例方法 :在
impl
块中定义的带有self
参数的函数,通过实例调用(如rect.area()
)&self
:不可变引用,用于只读操作&mut self
:可变引用,用于修改实例self
:获取所有权,调用后原实例不再可用
-
特质实现 :通过
impl Trait for Type
为类型实现特质,必须实现特质中所有的方法- 一个类型可以实现多个特质
- 一个特质可以被多个类型实现
- 这种机制实现了 Rust 中的多态性
-
新类型模式 :由于 Rust 不允许直接为基本类型(如
i32
、f64
)实现方法或特质,我们可以创建一个简单的结构体来包装基本类型(如示例中的Fahrenheit
和Celsius
),然后为这个新类型实现方法
impl ... for ...
是 Rust 中实现面向对象特性的核心机制,它允许我们将数据和行为关联起来,同时保持代码的灵活性和可扩展性。通过为不同类型实现相同的特质,我们可以写出通用的代码,实现多态行为。
具体代码参见
rust
// 1. 为结构体实现方法
struct Rectangle {
width: u32,
height: u32,
}
// 为Rectangle结构体实现方法
impl Rectangle {
// 关联函数(类似静态方法)
fn new(width: u32, height: u32) -> Self {
Rectangle { width, height }
}
// 实例方法
fn area(&self) -> u32 {
self.width * self.height
}
// 修改自身的方法
fn scale(&mut self, factor: u32) {
self.width *= factor;
self.height *= factor;
}
}
// 2. 为枚举实现方法
enum Calculator {
Add,
Subtract,
Multiply,
Divide,
}
impl Calculator {
// 实现计算功能的方法
fn calculate(&self, a: i32, b: i32) -> Option<i32> {
match self {
Calculator::Add => Some(a + b),
Calculator::Subtract => Some(a - b),
Calculator::Multiply => Some(a * b),
Calculator::Divide => {
if b == 0 {
None
} else {
Some(a / b)
}
}
}
}
// 返回操作符字符串
fn symbol(&self) -> &str {
match self {
Calculator::Add => "+",
Calculator::Subtract => "-",
Calculator::Multiply => "*",
Calculator::Divide => "/",
}
}
}
// 3. 为类型实现特质(trait)
// 定义一个特质
trait Shape {
fn area(&self) -> f64;
fn perimeter(&self) -> f64;
fn name(&self) -> &str;
}
// 定义一个圆形结构体
struct Circle {
radius: f64,
}
// 为Circle实现Shape特质
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
fn perimeter(&self) -> f64 {
2.0 * std::f64::consts::PI * self.radius
}
fn name(&self) -> &str {
"Circle"
}
}
// 4. 为基本类型实现方法(通过新类型模式)
// Rust不允许直接为基本类型实现方法,需要使用新类型包装
struct Fahrenheit(f64);
struct Celsius(f64);
impl Fahrenheit {
fn to_celsius(&self) -> Celsius {
Celsius((self.0 - 32.0) * 5.0 / 9.0)
}
}
impl Celsius {
fn to_fahrenheit(&self) -> Fahrenheit {
Fahrenheit(self.0 * 9.0 / 5.0 + 32.0)
}
}
// 5. 为多个类型实现同一特质
trait Printable {
fn print(&self);
}
impl Printable for i32 {
fn print(&self) {
println!("Integer value: {}", self);
}
}
impl Printable for String {
fn print(&self) {
println!("String value: '{}'", self);
}
}
impl Printable for bool {
fn print(&self) {
println!("Boolean value: {}", self);
}
}
fn main() {
// 演示结构体方法
let mut rect = Rectangle::new(10, 20);
println!("Rectangle area: {}", rect.area());
rect.scale(2);
println!("Scaled rectangle area: {}", rect.area());
// 演示枚举方法
let operations = [
Calculator::Add,
Calculator::Subtract,
Calculator::Multiply,
Calculator::Divide,
];
let a = 10;
let b = 5;
for op in operations.iter() {
match op.calculate(a, b) {
Some(result) => println!("{} {} {} = {}", a, op.symbol(), b, result),
None => println!("{} {} {} = Error", a, op.symbol(), b),
}
}
// 演示特质实现
let circle = Circle { radius: 5.0 };
println!("\n{} - Area: {:.2}, Perimeter: {:.2}",
circle.name(), circle.area(), circle.perimeter());
// 演示新类型模式
let temp_f = Fahrenheit(98.6);
let temp_c = temp_f.to_celsius();
println!("\n98.6°F = {:.1}°C", temp_c.0);
// 演示多类型特质实现
println!("\nPrintable values:");
42.print();
"Hello".to_string().print();
true.print();
}