[Chapter 5-3] Rust 메소드(method)

hwwwa·2021년 10월 28일
0

🦀 Rust

목록 보기
14/25
post-custom-banner

메소드(method)는 함수와 유사합니다. 하지만 메소드는 함수와 달리 구조체의 내용 안(혹은 열거형이나 트레잇 객체 안)에 정의됩니다. 첫 번째 파라미터가 언제나 self 인데 이는 메소드가 호출되고 있는 구조체의 인스턴스를 나타냅니다.

메소드 정의하기

chapter5-2의 코드를 수정해봅시다. Rectangle 인스턴스를 파라미터로 가지고 있는 area 함수를 변경하여 Rectangle 구조체 위에서 정의된 area 메소드를 만들어봅시다.

#[derive(Debug)]
struct Rectangle {
    length: u32,
    width: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.length * self.width
    }
}

fn main() {
    let rect1 = Rectangle { length: 50, width: 30 };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
}

Rectangle 의 내용 안에 함수를 정의하기 위해 impl 블록을 시작합니다. area 함수를 impl 중괄호 안으로 옮기고 시그니처 본체 내의 모든 곳에 있는 첫 번째 파라미터를 self로 변경합니다. main 함수에서는 Rectangle 인스턴스 상의 area 메소드를 호풀하기 위해 메소드 문법 (method syntax) 를 이용할 수 있습니다.

이전 코드에서 &Rectangle 을 사용한것과 같이 &self 를 사용했습니다. 소유권을 가져오는 것을 원하지 않고 데이터만 읽어오기 위함입니다.

더 많은 파라미터를 가진 메소드

이번에는 Rectangle 의 인스턴스가 다른 Rectangle 인스턴스를 가져와서 두 번째 Rectangleself 내에 완전히 들어갈 수 있다면 true를 반환하고 그렇지 않으면 false를 반환하도록 작성해봅시다.

impl Rectangle {
    fn area(&self) -> u32 {
        self.length * self.width
    }

    fn can_hold(&self, other: &Rectangle) -> bool {
        self.length > other.length && self.width > other.width
    }
}

fn main() {
    let rect1 = Rectangle { length: 50, width: 30 };
    let rect2 = Rectangle { length: 40, width: 10 };
    let rect3 = Rectangle { length: 45, width: 60 };

    println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
    println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
}

결과:

Can rect1 hold rect2? true
Can rect1 hold rect3? false

rect1.can_hold(&rect2)&rect2를 넘기고 있는데, 이는 Rectangle의 인스턴스인 rect2의 불변성 빌림입니다. 우리가 rect2를 그냥 읽기만 하길 원하기 때문입니다. mainrect2의 소유권을 유지하여 can_hold 메소드 호출 후에도 다시 사용할 수 있습니다.

연관 함수

self 파라미터를 갖지 않는 함수도 impl 내에 정의 가능합니다. 이를 연관 함수(associated functions) 라고 부릅니다. 이 함수가 해당 구조체와 연관되어 있기 때문입니다. 함께 동작할 구조체의 인스턴스를 가지고 있지 않기 때문에 메소드가 아니라 여전히 함수입니다.

연관 함수는 아래의 예시처럼 새로운 구조체의 인스턴스를 반환해주는 생성자로 주로 사용됩니다.

impl Rectangle {
    fn square(size: u32) -> Rectangle {
        Rectangle { length: size, width: size }
    }
}

연관 함수를 호출하지 위해서는 let sq = Rectangle::square(3); 처럼, 구조체 이름과 함께 :: 문법을 이용합니다.

post-custom-banner

0개의 댓글