Rust - 특성 이해하기 1

15239 단어 designbehaviorrust
소개

오늘날 많은 언어가 객체 지향적이며 이 패러다임을 지원하거나 직접 객체 지향적이지 않기 때문에 프로그래머가 자체 데이터 유형을 정의할 수 있습니다.

일반적으로 우리는 이러한 유형이 특정 상황에서 특정 행동 특성을 나타내기를 원합니다. 예를 들어 유형을 표준 출력으로 인쇄하거나 특정 유형을 반복할 수 있게 할 때 이러한 작업을 수행하는 방법을 알아야 합니다. 이것들은 우리의 유형이 일반적으로 트레잇에서 제공하는 특정 메소드를 구현하는지 확인함으로써 정의됩니다.

특성

특성은 알 수 없는 유형인 Self에 대해 정의된 메서드 모음입니다. 그들은 같은 트레잇에 선언된 다른 메소드에 접근할 수 있습니다.

모든 데이터 유형에 대해 특성을 구현할 수 있습니다. 아래 예에서는 메서드 그룹인 Animal을 정의합니다.

trait Animal {
    // Static method signature; `Self` refers to the implementor type.
    fn new(name: &'static str) -> Self;

    // Instance method signatures; these will return a string.
    fn name(&self) -> &'static str;
    fn noise(&self) -> &'static str;

    // Traits can provide default method definitions.
    fn talk(&self) {
        println!("{} says {}", self.name(), self.noise());
    }
}

이 특성을 정의했으므로 이제 고유한 유형이 이 특성을 구현하도록 할 수 있습니다. 즉, 고유한 기능을 추가하면서 동물의 모든 동작을 갖게 됩니다.

동물의 예로서 두 가지 완전히 다른 동물 유형을 정의할 수 있습니다. a StuffedAnimal 및 a Cat . 둘 다 동물이기 때문에 이름을 부르고 말하고 소리를 내는 것과 같은 몇 가지 공통된 특성을 공유하지만 인형을 지칭하는 것인지 실제 고양이를 지칭하는 것인지에 따라 행동 방식이 다릅니다. 유형이 특정 특성을 구현하도록 하는 방법을 살펴보겠습니다.

사용자 정의 유형이 특성을 구현하도록 만들기

시작하려면 먼저 설명하려는 개념을 나타내는 매우 기본적인 두 가지 사용자 정의 유형인 박제 동물과 고양이를 정의합니다.

struct Cat {
    name: &'static str,
    age: i32
}

struct StuffedAnimal {
    name: &'static str
}

여기서 고양이는 단순히 이름과 나이로 표현되고, 박제된 동물은 단순히 이름이 있습니다.

현재로서는 이러한 유형을 다음과 같이 인스턴스화하고 사용할 수 있습니다.

fn main() {
  let c=Cat{name: "Bobi",age:8};
  println!("Cat's name is {} and he is {} years old",c.name, c.age);
}

따라서 유형을 나타내는 속성을 활용하여 코드에서 특정 개념의 상위 수준 표현으로 작업할 수 있습니다.

특성을 사용하면 이 아이디어를 확장할 수 있습니다. 본질적으로 유형이 구현하는 특성에 의해 정의된 동작을 나타내기 때문입니다. 우리의 특별한 경우에 우리는 우리 유형을 "동물"로 "볼"수 있을 것입니다. 왜냐하면 그들은 특정한 소음과 대화할 수 있기 때문입니다. 위에서 본 new() 메서드를 사용하여 인스턴스화할 수도 있습니다. 이 메서드는 위에서 본 "손으로 만든"구조체 생성을 단순히 참조합니다.

유형에 대한 특성을 구현하는 방법은 다음과 같습니다.

impl Animal for Cat {
    // `Self` is the implementor type: `Cat`.
    fn new(name: &'static str) -> Cat {
        Cat { name: name, age: 1 }
    }

    fn name(&self) -> &'static str {
        self.name
    }

    fn noise(&self) -> &'static str {
        "Meowww"
    }

    // Default trait methods can be overridden.
    fn talk(&self) {
        // For example, we can add some quiet contemplation.
        println!("{} pauses briefly... {}", self.name, self.noise());
    }
}

여기서 사용할 구문은 헤더 선언으로 impl <trait name> for <type name> 유형이며, 다른 많은 언어와 마찬가지로 정의 및 실제 특성 구현에서 기본 구현에 따라 원하는 메서드에 대한 구현을 정의합니다. 보시다시피 고양이는 소리를 낼 때 야옹합니다.

여기서 주목해야 할 또 다른 중요한 점은 기본 특성 메서드를 재정의할 수 있다는 것입니다. 이 특정 예에서는 고양이의 특정 경우에 대해 talk() 메서드를 재정의합니다.

이것이 사용자 정의 유형에 대한 특성을 정의하는 방법입니다.

전체 예

완전한 예로서, 우리는 또한 박제된 동물에 대한 특성을 구현할 수 있습니다:

trait Animal {
    // Static method signature; `Self` refers to the implementor type.
    fn new(name: &'static str) -> Self;

    // Instance method signatures; these will return a string.
    fn name(&self) -> &'static str;
    fn noise(&self) -> &'static str;

    // Traits can provide default method definitions.
    fn talk(&self) {
        println!("{} says {}", self.name(), self.noise());
    }
}

struct Cat {
    name: &'static str,
    age: i32
}

struct StuffedAnimal {
    name: &'static str
}

impl Animal for Cat {
    fn new(name: &'static str) -> Cat {
        Cat { name: name, age: 1 }
    }

    fn name(&self) -> &'static str {
        self.name
    }

    fn noise(&self) -> &'static str {
        "Meowww"
    }

    // Default trait methods can be overridden.
    fn talk(&self) {
        // For example, we can add some quiet contemplation.
        println!("{} pauses briefly... {}", self.name, self.noise());
    }
}

impl Animal for StuffedAnimal {
    fn new(name: &'static str) -> StuffedAnimal {
        StuffedAnimal { name: name}
    }

    fn name(&self) -> &'static str {
        self.name
    }

    fn noise(&self) -> &'static str {
        "<random factory noise>"
    }
}

fn main() {
  let c: Cat=Animal::new("Bobi");
  println!("Cat's name is {} {} ",c.name(), c.age);
  c.talk();

  let stuffed: StuffedAnimal=Animal::new("BobiStuffed");
  stuffed.talk();
}

따라서 이것을 실행할 때 특성의 구현에 따라 다른 동작을 얻을 수 있음을 알 수 있습니다. 또한 talk 메소드는 두 번째 예에서 기본 구현을 리턴한다는 점에 유의하십시오.

결론

특성에 대한 이 기본 소개 후에는 자신의 유형에 대한 사용자 정의 특성 구현을 추가하고 유형을 더 다양하고 문제 영역에 더 가깝게 만들 수 있어야 합니다! 더 많은 Rust를 기대해 주세요!

좋은 웹페이지 즐겨찾기