NeuroWhAI의 잡블로그

[Rust] Sealed trait 본문

개발 및 공부/설계

[Rust] Sealed trait

NeuroWhAI 2019. 11. 18. 22:00


출처 : https://rust-lang.github.io/api-guidelines/future-proofing.html

 

C++이나 C#에 보면 sealed라는 키워드가 있습니다.
이걸로 수식된 클래스는 상속의 끝을 뜻하며 자식 클래스를 가질 수 없죠.
보통 다른 개발자가 의도치 않게 자신의 클래스를 상속하고 확장하는 것을 방지하기 위한 용도로 쓰입니다.
Rust에서도 이와 비슷한 목적으로 trait을 sealed 시킬 수 있습니다.
다만 키워드로 지원하는 것은 아니고 문법을 이용합니다.
다른 개발자가 trait을 사용할 수는 있어도 다른 타입에 impl하는 것은 막는 것이죠.

pub trait Foo: private::Sealed {
    fn foo(&self);
}

impl Foo for usize {
    fn foo(&self) {
        // ...
    }
}

mod private {
    pub trait Sealed {}

    impl Sealed for usize {}
}

이걸 라이브러리 코드의 일부라고 해봅시다.
Foo라는 trait이 private 모듈에 있는 Sealed trait을 상속하고 있습니다.
그리고 임의의 타입 usize에 Foo를 impl하였습니다.
일단 여기까지만 보면 이 라이브러리를 쓸 다른 개발자들은 Foo trait object도 만들 수 있고 Foo를 use하여 usize에서 foo 함수도 쓸 수 있으니 다른 trait과 별반 다르지 않습니다.
그런데 그 외부 개발자가 다른 타입(예: i32)에 우리의 Foo를 impl하려고 하면 문제가 발생합니다.

impl ourlib::Foo for i32 {
    fn foo(&self) {
        // ...
    }
}
error[E0277]: the trait bound `i32: ourlib::private::Sealed` is not satisfied

Rust에선 어떤 trait을 impl하려면 그 trait의 부모 trait도 모두 impl 해줘야만 합니다.
Foo엔 Sealed를 impl하지 않아서 저 에러가 발생하는 것이죠.
그런데 우리 라이브러리의 private 모듈을 pub로 공개하지 않는 이상 Sealed는 라이브러리 개발자만 접근할 수 있습니다.
짠! Sealed 기능을 만들었습니다.

출처에도 나와있지만 이렇게 하고 나서 문서로도 이 trait은 상속이 불가하다는 것을 알려주면 최고라고 하네요.
그럼 끝.



Comments