解构方法语法

方法(method)与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义(或者是枚举或 trait 对象的上下文),并且它们第一个参数总是 self,它代表调用该方法的结构体实例。

定义方法

#[derive(Debug)] struct Rectangle { width: u32, height: u32, } // impl 是 implementation 的缩写 impl Rectangle { // 定义方法 // self 代表结构体实例本身 fn area(&self) -> u32 { self.width * self.height } } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; println!( "The area of the rectangle is {} square pixels.", rect1.area() ); }
#[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { // 我们可以在 Rectangle 上定义一个方法,并命名为 width: fn width(&self) -> bool { self.width > 0 } } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; // 在 main 中, // 当我们在 rect1.width 后面加上括号时。Rust 知道我们指的是方法 width。 // 当我们不使用圆括号时,Rust 知道我们指的是字段 width。 if rect1.width() { println!("The rectangle has a nonzero width; it is {}", rect1.width); } }

带有更多参数的方法

#[derive(Debug)] struct Rectangle { width: u32, height: u32, } // 所有在 impl 块中定义的函数被称为 关联函数(associated functions), impl Rectangle { fn area(&self) -> u32 { self.width * self.height } fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; let rect2 = Rectangle { width: 10, height: 40, }; let rect3 = Rectangle { width: 60, height: 45, }; println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); }

关联函数

所有在 impl 块中定义的函数被称为 关联函数(associated functions),因为它们与 impl 后面命名的类型相关。

我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。

String 类型上定义的 String::from 函数 就是这样的一个关联函数

不是方法的关联函数经常被用作返回一个结构体新实例的构造函数:

#[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { // 非方法的关联函数 fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size, } } } fn main() { let sq = Rectangle::square(3); }

多个 impl 块

每个结构体都允许拥有多个 impl 块。

#[derive(Debug)] struct Rectangle { width: u32, height: u32, } // impl 块1 impl Rectangle { fn area(&self) -> u32 { self.width * self.height } } // impl 块2 impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; let rect2 = Rectangle { width: 10, height: 40, }; let rect3 = Rectangle { width: 60, height: 45, }; println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); }