복합 데이터에 열거형 변형 사용

완료됨

열거형은 여러 변형 중 하나가 될 수 있는 형식입니다. Rust에서 열거형이라고 부르는 것은 일반적으로 대수 데이터 형식으로 알려져 있습니다. 중요한 세부 정보는 각 열거형 변형에 데이터를 포함할 수 있다는 것입니다.

enum 키워드를 사용하여 열거형 변형의 조합을 포함할 수 있는 열거형 형식을 만듭니다. 구조체와 마찬가지로 열거형 변형에는 이름 있는 필드가 있지만, 이름 없는 필드가 있거나 필드가 없을 수 있습니다. 구조체 형식처럼 열거형 형식도 대문자로 시작합니다.

열거형 정의

다음 예제에서는 웹 이벤트를 분류하는 열거형을 정의합니다. 열거형의 각 변형은 독립적이며 다른 크기와 유형의 값을 저장합니다.

enum WebEvent {
    // An enum variant can be like a unit struct without fields or data types
    WELoad,
    // An enum variant can be like a tuple struct with data types but no named fields
    WEKeys(String, char),
    // An enum variant can be like a classic struct with named fields and their data types
    WEClick { x: i64, y: i64 }
}

이 예제의 열거형에는 형식이 다른 세 가지 변형이 있습니다.

  • WELoad는 연결된 데이터 형식 또는 데이터가 없습니다.
  • WEKeys에는 데이터 형식 Stringchar가 있는 필드가 두 개 있습니다.
  • WEMClick에는 이름이 있는 필드 xy가 있는 익명 구조체와 그 데이터 형식(i64)이 있습니다.

다양한 종류의 구조체 형식을 정의하는 방법과 유사한 변형을 사용하여 열거형을 정의합니다. 모든 변형은 동일한 WebEvent 열거형 형식으로 그룹화됩니다. 열거형의 각 변형은 자체 형식이 아닙니다. WebEvent 열거형의 변형을 사용하는 함수는 열거형의 모든 변형을 허용해야 합니다. WEClick 변형만 허용하고 나머지 변형은 허용하지 않는 함수는 없습니다.

구조체를 사용하여 열거형 정의

열거형 변형 요구 사항을 해결하는 방법은 열거형의 각 변형에 대해 별도의 구조체를 정의하는 것입니다. 그러면 열거형의 각 변형이 해당 구조체를 사용합니다. 구조체는 해당 열거형 변형에 있던 것과 동일한 데이터를 보유합니다. 이 스타일의 정의를 통해 각 논리적 변형을 단독으로 참조할 수 있습니다.

다음 코드는 이 대체 정의 스타일을 사용하는 방법을 보여줍니다. 구조체는 데이터를 보관하도록 정의됩니다. 열거형의 변형은 구조체를 참조하도록 정의됩니다.

// Define a tuple struct
struct KeyPress(String, char);

// Define a classic struct
struct MouseClick { x: i64, y: i64 }

// Redefine the enum variants to use the data from the new structs
// Update the page Load variant to have the boolean type
enum WebEvent { WELoad(bool), WEClick(MouseClick), WEKeys(KeyPress) }

열거형 인스턴스화

이제 열거형 변형의 인스턴스를 만드는 코드를 추가해보겠습니다. 각 변형에 대해 let 키워드를 사용하여 할당합니다. 열거형 정의의 특정 변형에 액세스하려면 이중 콜론 ::이 있는 구문 <enum>::<variant>을 사용합니다.

단순 변형: WELoad(bool)

WebEvent 열거형의 첫 번째 변형에는 단일 부울 값 WELoad(bool)가 있습니다. 앞 단원에서 부울을 사용했던 방법과 비슷한 방식으로 이 변형을 인스턴스화합니다.

let we_load = WebEvent::WELoad(true);

구조체 변형: WEClick(MouseClick)

두 번째 변형에는 클래식 구조체 WEClick(MouseClick)이 포함되어 있습니다. 이 구조체에는 이름 있는 필드 xy가 있으며 두 필드 모두 데이터 형식이 i64입니다. 이 변형을 만들려면 먼저 구조체를 인스턴스화합니다. 그런 다음, 호출에서 구조체를 인수로 전달하여 변형을 인스턴스화합니다.

// Instantiate a MouseClick struct and bind the coordinate values
let click = MouseClick { x: 100, y: 250 };

// Set the WEClick variant to use the data in the click struct
let we_click = WebEvent::WEClick(click);

튜플 변형: WEKeys(KeyPress)

마지막 변형에는 튜플 WEKeys(KeyPress)가 있습니다. 이 튜플에는 Stringchar 데이터 형식을 사용하는 필드 두 개가 있습니다. 이 변형을 만들려면 먼저 튜플을 인스턴스화합니다. 그런 다음, 호출에서 튜플을 인수로 전달하여 변형을 인스턴스화합니다.

// Instantiate a KeyPress tuple and bind the key values
let keys = KeyPress(String::from("Ctrl+"), 'N');
    
// Set the WEKeys variant to use the data in the keys tuple
let we_key = WebEvent::WEKeys(keys);

이 코드 조각에서는 String::from("<value>") 구문을 사용합니다. 이 구문은 Rust from 메서드를 호출하여 형식 String 값을 만듭니다. 이 메서드는 큰따옴표로 묶인 데이터의 입력 인수를 예상합니다.

열거형 예제

다음은 열거형 변형을 인스턴스화할 최종 코드입니다.

// Define a tuple struct
#[derive(Debug)]
struct KeyPress(String, char);

// Define a classic struct
#[derive(Debug)]
struct MouseClick { x: i64, y: i64 }

// Define the WebEvent enum variants to use the data from the structs
// and a boolean type for the page Load variant
#[derive(Debug)]
enum WebEvent { WELoad(bool), WEClick(MouseClick), WEKeys(KeyPress) }

fn main() {
    // Instantiate a MouseClick struct and bind the coordinate values
    let click = MouseClick { x: 100, y: 250 };
    println!("Mouse click location: {}, {}", click.x, click.y);
        
    // Instantiate a KeyPress tuple and bind the key values
    let keys = KeyPress(String::from("Ctrl+"), 'N');
    println!("\nKeys pressed: {}{}", keys.0, keys.1);
        
    // Instantiate WebEvent enum variants
    // Set the boolean page Load value to true
    let we_load = WebEvent::WELoad(true);
    // Set the WEClick variant to use the data in the click struct
    let we_click = WebEvent::WEClick(click);
    // Set the WEKeys variant to use the data in the keys tuple
    let we_key = WebEvent::WEKeys(keys);
        
    // Print the values in the WebEvent enum variants
    // Use the {:#?} syntax to display the enum structure and data in a readable form
    println!("\nWebEvent enum structure: \n\n {:#?} \n\n {:#?} \n\n {:#?}", we_load, we_click, we_key);
}

Rust Playground에서 이 예제 코드와 상호 작용해봅니다.

디버그 문

이전 예제에서 다음 코드 문을 찾습니다. 이 문은 코드의 여러 위치에 사용됩니다.

// Set the Debug flag so we can check the data in the output
#[derive(Debug)]

#[derive(Debug)] 구문을 사용하면 코드 실행 시 표준 출력에서 볼 수 없는 특정 값을 볼 수 있습니다. println! 매크로를 사용하여 디버그 데이터를 볼 수 있도록 구문 {:#?}을 사용하여 읽을 수 있는 방식으로 데이터의 형식을 지정합니다.

지식 점검

다음 질문에 대답하여 배운 내용을 확인하세요. 각 질문에 대해 하나의 대답을 선택한 다음, 답변 확인을 선택합니다.

1.

Rust 열거형의 모든 변형은 동일한 형식으로 그룹화됩니다. 열거형의 변형을 사용하는 함수는 모든 변형을 허용해야 합니다. 이러한 열거형 변형 요구 사항을 해결하려면 어떻게 해야 할까요?