Fluent Rust - Use of wildcard with Enum

Migo·2023년 9월 6일
0

Fluent Rust

목록 보기
8/27
post-thumbnail

Rust의 Type시스템은 강력하다 - 너무 강력해서, 현업코드에서도 타입시스템을 믿고 Refactoring하는 경우가 많다.

가령 Enum타입은, 내부 요소로 존재하는 모든 variants들에 대해서, match clause안에서 반드시 매치되길 강제한다. 아래 코드를 보자.

enum MySpecialEnumCollection {
    Variant1,
    Variant2,
    Variant3,
    Variant4,
}

fn main() {
    let em = MySpecialEnumCollection::Variant1;

    match em { // Error!
        MySpecialEnumCollection::Variant1 => todo!(),
        MySpecialEnumCollection::Variant2 => todo!(),
        MySpecialEnumCollection::Variant3 => todo!(),
    }
}

위의 코드는 아래와 같은 에러메세지를 띄운다.

missing match arm: Variant4 not covered

이는, 추후 enum의 특정 variant가 추가되는 등의 요구사항이 있을 때 변경요구지점에 대한 모든 부분들을 컴파일러가 아주 손쉽게 찾아줄 수 있도록 하여, Refactoring을 아주 쉽게한다.

그러나

예제코드의 enum 명을 다시 보자 - MySpecialEnumCollection.

태생이 귀찮음이 많은 개발자라면, 내부 요소들에 대해서, wildcard를 사용해보고 싶은 충동이 들 수 있겠다. 그리고 Rust는 그런 접근도 허용한다.

enum MySpecialEnumCollection {
    Variant1,
    Variant2,
    Variant3,
    Variant4,
}

fn main() {
    let em = MySpecialEnumCollection::Variant1;

    use MySpecialEnumCollection::*;
    
    match em { //works!
        Variant1 => todo!(),
        Variant2 => todo!(),
        Variant3 => todo!(),
        Variant4 => todo!(),
    }
}

그러나, 위와 같은 방법은 현업코드에서 절.대.로 추천하지 않는다. 그 이유는, 그러한 practice가 컴파일러를 통한 에러 표시 기능을 침묵시킬 수 있기 때문이다.

위의 코드에서 가령, Variant4를 없애고, Varaint5, Varaint6을 추가했다고 생각해보자.

enum MySpecialEnumCollection {
    Variant1,
    Variant2,
    Variant3,
    // Variant4 removed
    Variant5, // added
    Variant6, // added
}

fn main() {
    let em = MySpecialEnumCollection::Variant1;

    use MySpecialEnumCollection::*;
    match em { // !! still works!
        Variant1 => todo!(),
        Variant2 => todo!(),
        Variant3 => todo!(),
        Variant4 => todo!(), 
    }
}

위의 코드는 정상 작동한다. 그 이유는 Match clause에서 Variant4Variant1~3을 제외한 다른 케이스에 대한 변수로 작동하여, 매칭 패턴을 만족시키기 때문이다.

따라서, Enum에 대해 wildcard를 사용하는 패턴은 현업코드에서는 절.대.로 추천하지 않는다.

혹여, 너무 긴 Enum이 문제라면 대신에 아래와 같이 alias를 사용하도록 하자.

...
    use MySpecialEnumCollection as EC;
    match em {
        EC::Variant1 => todo!(),
        EC::Variant2 => todo!(),
        EC::Variant3 => todo!(),
...
       
profile
Dude with existential crisis

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN