第八节、Method方法
方法Method
方法和函数类似定义用fn,但是方法有个默认的参数self。他是定义在struct里面,代码如下:
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
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() //调用的时候是某个实例调用的
);
}
为了在struct内定义method的功能,要采用impl(实现)块。
在上面例子中area有一个参数&self, 没有写成函数的参数写法rectangle: &Rectangle
;
这里&self,其实是self: &Self。在实现块impl内部,Self是 impl实现类型名的别名。
上面的例子,Self就是Rectangle的别名。self前面加了&表明是借用,没有可修改的所有权。
方法可以有多个参数,例如下面的例子:
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
}
}
struct Rectangle {
width: u32,
height: u32,
}
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));
}
可变self示例
impl Rectangle {
fn check(&mut self){
if self.width > 40{
self.width = 40
}
}
}
....
let mut rect3 = Rectangle {
width: 60,
height: 45,
};
rect3.check();
println!("{:#?}",rect3);
.....
Rectangle {
width: 40,
height: 45,
}
同一个结构体是允许多实现块定义的:
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
关联函数
关联函数和方法函数是不一样的。我们之前用过String::from,就是一个关联函数。 这里定义一个Rectangle函数的示例代码如下:
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}