Rust 녹슬지 않을 언어

Rust에서 struct와 impl을 따로 두는 이유? 매개변수 self를 사용하는 이유에 대하여(Rust, impl, &self, struct)

젊은우산 2024. 3. 3. 13:34
반응형

    Rust에서 구조체를 선언하고 사용할 메서드(구현함수)를 정의할 때는 impl 블록을 사용한다.

이때 메서드(구현함수)의 첫 번째 매개변수로 항상 &self를 사용하여 해당 메서드가 호출된 구조체의 인스턴스에 대한 참조(레퍼런스)를 전달한다.

 

인스턴스란?

  • 사람이라는 클래스가 있다면, 세계 50억명 이상의 각 개인들의 인스터스가 있는 것을 말한다. 즉 인스턴스란 클래스의 정의를 통해 만들어진 객체를 의미한다.

참조(레퍼런스 &reference)란?

  • c언어를 사용한 사람들이라면 포인터 라고 말하는것이 친숙할 것
  • 변수 값을 나타내는 것이 아닌, 주소값 만을 받아와서 전달하는 것. 주로 읽을때 사용 

    Rust에서 구조체의 데이터를 읽고만 싶을 때는, impl 메서드의 매개변수를 &self를 사용한다. 이렇게 함으로써 해당 메서드가 구조체의 상태를 변경할 수 있도록 허용되는지 여부를 결정할 수 있다. 만약 메서드가 구조체의 상태를 변경하지 않고 단순히 읽기만 한다면 &self를 사용한다.

  • 함수의 인자로 구조체의 레퍼런스를 가져오는 것은 일반적인 Rust의 스타일
  • 이것은 메모리 소유권과 관련된 Rust의 중요한 개념 중 하나인 '대여 (borrowing)'에 해당
  • 함수는 구조체의 소유권을 가져가지 않고도 그 구조체의 일부를 사용할 수 있게 해줌

 

아래는 예시 코드다.

// 구조체 정의
struct MyStruct {
    data: i32,
}

// 구조체에 대한 메서드 구현
impl MyStruct {
    // 첫 번째 매개변수로 &self를 사용하여 해당 인스턴스에 대한 참조를 전달
    fn print_data(&self) {
        println!("Data: {}", self.data);
    }

    // 다른 인스턴스와의 비교를 위한 메서드
    fn compare_data(&self, other: &MyStruct) {
        if self.data == other.data {
            println!("Data is equal");
        } else {
            println!("Data is not equal");
        }
    }
}

fn main() {
    let instance1 = MyStruct { data: 10 };
    let instance2 = MyStruct { data: 20 };

    // 메서드 호출
    instance1.print_data(); // 출력: Data: 10
    instance2.print_data(); // 출력: Data: 20

    instance1.compare_data(&instance2); // 출력: Data is not equal
}

위 코드에서

  • print_data 메서드는 해당 구조체의 데이터를 출력하기만 하므로 &self를 사용하여 해당 인스턴스에 대한 참조를 받는다.
  • compare_data 메서드는 다른 구조체 인스턴스와 비교하기 위해 또 다른 구조체의 참조를 받기 때문에 두 번째 매개변수로
    other: &MyStruct를 사용한다.

  이는 구조체 MyStruct의 인스턴스에 대한 참조를 가져오겠다는 의미이다. 이것은 해당 메서드가 호출될 때 다른 MyStruct구조체 인스턴스에 대한 참조를 비교할 수 있게 한다.

 

 
 
 
반응형