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,
}
}
}