Post

[RUST] 러스트 프로그래밍 공식 가이드(제2판) 17장 요약

러스트의 객체 지향 프로그래밍 기능

객체 지향 언어의 특성

객체는 데이터와 동작을 담습니다

  • 러스트의 구조체와 열거형이 객체라고 호칭되지는 않더라도 데이터가 있고, impl 블록은 그 구조체와 열거형에 대한 메서드를 제공하기 때문에 러스트는 객체 지향적 이라 볼 수 있음

상세 구현을 은닉하는 캡슐화

  • OOP와 연관된 또 다른 측면은 캡슐화(encapsulation) 개념으로, 객체를 이용하는 코드에서 그 객체의 상세 구현에 접근할 수 없게 하고 공개 API 를 통해서만 객체와 상호작용할 수 있도록 함
  • 코드의 서로 다른 부분들에 대해 pub을 사용할지 여부를 선택하는 옵션을 통해 구현 세부사항을 캡슐화 할 수 있으므로, 캡슐화가 객체 지향 언어로 간주하기 위해 필요한 측면이라면, 러스트는 해당 요구 사항을 충족함

타입 시스템과 코드 공유로서의 상속

  • 상속(inheritance)은 어떤 객체가 다른 객체의 정의로부터 요소를 상속받을 수 있는 메커니즘으로, 이를 통해 객체를 다시 정의하지 않고도 부모 객체의 데이터와 동작을 가져올 수 있음
  • 만약 객체 지향 언어가 반드시 상속을 제공해야 한다면, 러스트는 매크로를 사용하지 않고 부모 구조체의 필드와 메서드 구현을 상속받는 구조체를 정의할 방법이 없음
  • 상속의 주요 목적 중 하나는 코드 재사용 (기존 구현을 다른 타입에 활용)
    • 러스트에서는 상속 대신 트레잇의 기본 메서드 구현을 사용하여 코드를 재사용 할 수 있음
    • 트레잇을 구현한 타입은 트레잇이 제공하는 기본 메서드 구현을 그대로 사용할 수도 있고, 필요하면 그 메서드를 오버라이딩 하여 새로 정의할 수도 있음
  • 상속의 주요 목적 중 또 다른 하나는 다형성(polymorphism) (부모 타입 자리에 자식 타입을 넣어도 동작)
    • 러스트는 대신 제네릭을 사용하여 호환 가능한 타입을 추상화하고 트레이트 바운드를 이용하여 해당 타입들이 반드시 제공해야하는 제약을 부과하는데 이를 범주 내 매개변수형 다형성 라 부름

트레이트 객체를 사용하여 다른 타입의 값 허용하기

공통된 동작을 위한 트레이트 정의하기

  • 벡터 타입은 한 번에 하나의 타입만을 저장할 수 있어 이를 해결하기 위해 열거형을 이용하여 여러 타입을 하나의 컬렉션에 담았는데, 이는 미리 정해진 타입들만 가능하다는 단점이 있음
  • 트레이트 객체는 특정 트레이트를 구현한 타입의 인스턴스와 런타임에 해당 타입의 트레이트 메서드를 조회하는데 사용되는 테이블 모두를 가리킴
  • &참조자나 Box 스마트 포인터와 같은 포인터 종류로 지정한 다음 dyn 키워드를 붙이고, 그 뒤에 관련된 트레이트를 특정하면 트레이트 객체를 생성할 수 있음 (`Box` 와 같이 사용됨)
  • 트레이트 객체를 사용하는 곳이 어디든, 러스트의 타입 시스템은 컴파일 타임에 해당 콘텍스트에서 사용된 모든 값이 트레이트 객체의 트레이트를 구현할 것을 보장하여 컴파일 타임에 모든 가능한 타입을 알 필요가 없음
  • 트레이트 객체는 트레이트 객체에 데이터를 추가할 수 없음
  • 트레이트 객체의 목적은 공통된 동작에 대한 추상화를 가능하도록 하는 것

트레이트 객체는 동적 디스패치를 수행합니다

  • 반형상화로부터 야기된 코드는 정적 디스패치를 수행하는데, 이는 호출하고자 하는 메서드가 어떤 것인지 컴파일러가 컴파일 시점에 알고있는 것을 말함
  • 동적 디스패치는 컴파일러가 호출하는 메서드를 컴파일 시점에 알 수 없을 경우 수행되며, 컴파일러는 런타임에 어떤 메서드가 호출되는지 알아내는 코드를 생성함
  • 트레이트 객체의 경우, 컴파일러는 트레이트 객체를 사용 중인 코드와 함께 사용될 수 있는 모든 타입을 알지 못하므로, 어떤 타입에 구현된 어떤 메서드가 호출될지 알지 못하기 때문에 동적 디스패치를 이용함
  • 트레이트 객체는 런타임에 트레이트 객체 내에 존재하는 포인터를 사용하여 어떤 메서드가 호출될지 알아냄
    • 이러한 조회는 정적 디스패치 시에는 발생하지 않을 런타임 비용을 만들어냄
  • 동적 디스패치는 컴파일러가 메서드의 코드를 인라인화 하는 선택을 막아버리는데, 이것이 결과적으로 몇 가지 최적화를 수행하지 못하게 함 (하지만, 추가적인 유연성을 얻었으므로, 고려할 만한 절충안임)
This post is licensed under CC BY 4.0 by the author.