Skip to content

第八节、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
    }
}
can_hold方法就是有两个参数,默认的参数就是调用实例自身,第二个是传进来的参数。完整代码如下 :
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,
        }
    }
}
使用方法let sq = Rectangle::square(3);要用"::"语法。