RustArena

Step 1 of 7

impl blocks and your first method

In the structs module you wrote functions like fn total_value(items: &[Item]). They work, but they float free: nothing ties them to the type, and you have to know their names to find them. A method is a function that belongs to a type. You define it inside an impl block (short for implementation), and its first parameter is self: the value the method was called on.

struct Rect {
    width: u32,
    height: u32,
}

impl Rect {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn is_square(&self) -> bool {
        self.width == self.height
    }
}

fn main() {
    let r = Rect { width: 8, height: 5 };
    println!("area: {}", r.area());
    println!("square? {}", r.is_square());
}
area: 40
square? false

Piece by piece:

In fact r.area() is just a nicer way to write Rect::area(&r), and both compile to exactly the same code. Methods are about organization, not speed:

Common mistakes

struct Rect {
    width: u32,
    height: u32,
}

impl Rect {
    fn area() -> u32 {
        self.width * self.height
    }
}

fn main() {
    let r = Rect { width: 2, height: 3 };
    println!("{}", r.area());
}
error[E0424]: cannot find value `self` in this scope

Your task

Fill in the blanks so the program prints perimeter: 28: the keyword that starts the block, the parameter that borrows the square, the value whose side you read, and the method call.

Challenge 2

Add two methods to Rect:

A method can take more parameters after self, like any function.

Challenge 3

Write an impl block for Time (hours and minutes on a 24-hour clock) with two methods:

Next: &mut self: methods that change the value