method는 function과 유사하다. 함수는 fn 키워드를 통해 선언하며, parameter를 가질 수 있고 값을 반환한다. 함수와 다르게 method는 struct(enum, trait object 등등)의 context 안에서 정의된다.
Rectangle instance를 매개변수로 받는 함수를 Rectangle struct 내부에서 정의되는 area method로 정의해보자.
#[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()
);
}
Rectangle 내부에서 정의하기 위해선 Rectangle을 위한 impl(implementation) 블록으로 시작한다. 함수에서 메소드로 바꾸면서 첫 매개변수는 rectangle: &Rectangle 대신에 &self로 받는다. &self는 self: &Self가 축약된 형태이다. &self를 사용하면서 소유권을 가지지 않고 immutable한 reference를 사용한다. 만약 구조체의 값이 변하길 원한다면 &mut self를 사용하여 가변 참조자를 사용한다.
함수가 아닌 메소드를 사용하는 가장 큰 이유는 Rectangle의 기능을 검색할 필요 없이 struct의 instance로 할 수 있는 모든 작업을 하나의 impl 블록에 넣었다는 것이다.
C++에서 포인터에서 역참조후에 메소드를 호출할 때,
->를 쓰는 경우를 본 적이 있을 것이다. Rust에서는 automatic refecnging and dereferencing을 활용해 자동으로&,&mut혹은*을 추가해준다.
impl 블록에 정의돈 함수는 impl 키워드 뒤에 나오는 type에 종속되어 있다. 우리는 때로 struct의 새로운 instance를 반환하기 위해서 생성자를 사용해야 할 때도 있다. 이러한 경우, 반환 타입을 Self로 지정하면 된다.
impl Rectangle {
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}