-
[Rust] 6. enum과 match에 대하여rust 2023. 2. 2. 08:27반응형
- 하나의 토픽내에 여러가지 상황이 존재하지만 한번에 하나의 상태만 존재하는 경우 enum type 을 사용할수 있다.
- ::문법을 통해 인스턴스를 생성한다.
enum IpAddrKind { V4, V6, } let four = IpAddrKind::V4; let six = IpAddrKind::V6;
- enum의 각 변수에 우리는 값을 직접 할당해줄수 있다.
- 같은 enum 이라고 변수별로 같은 타입의 값을 가져야 하는 것은 아니다
- 다양한 타입이 변수에 들어갈수 있으며 struct형태역시 가능하다.
enum IpAddr { V4(u8, u8, u8, u8), V6(String), } let home = IpAddr::V4(127, 0, 0, 1); let loopback = IpAddr::V6(String::from("::1")); enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }
- enum 역시 struct 처럼 method 를 가질수 있으며 enum 역시 값을 가질수 있기때문에 해당 enum 의 filed 에 할당된 값이 self 로 메서드에서 첫번째 인자로 사용된다.
impl Message { fn call(&self) { // method body would be defined here } } let m = Message::Write(String::from("hello")); m.call();
- 가장 많이 알려진 enum type 으로 Option 이 존재하며 값의 존재를 확신하지 못하는 경우 사용되는 타입이다. 해당 타입은 None, Some 의 필드를 가지며 none 의 경우 다른 언어에서 null과 같은 의미로 사용된다.
- null 일수 있는 값은 option 형태로 따로 처리되게 됨으로 예측하기 힘든 null 의 쓰임을 방지하여 안정성을 높이려는 의도가 담겨있다.
- 이때 enum 의 각 형태에 따른 분기를 match 를 통해서 할수 있다.
enum Option<T> { None, Some(T), }
- match 는 enum과 같이 많이 쓰이는 흐름제어자 이다.
- enum 의 모든값에 대한 케이스를 지정해 줘야 한다.
- if 와 비슷하지만 컨디션에 들어갈수 있는 값이 bool 형태가 아닌 다양한 형태가 될수있다.(enum의 특성)
enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } }
- enum 의 각변수는 값을 가질수 있고 match 에서 케이스 처리시에 각 변수의 값은 아래와 같이 바인딩 되어 사용할수 있다.
fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter(state) => { println!("State quarter from {:?}!", state); 25 } } }
- match는 완전히 모든케이스를 처리(cover)해 줘야한다.
- match가 꼭 enum 하고만 같이 쓰이는 control flow 는 아니다 다만 enum과 같이 쓰일때 위와같이 처리해줘야한다.
- 나머지 케이스들을 other 키워드로 묶어서 같이 처리할수있다.
let dice_roll = 9; match dice_roll { 3 => add_fancy_hat(), 7 => remove_fancy_hat(), other => move_player(other), } fn add_fancy_hat() {} fn remove_fancy_hat() {} fn move_player(num_spaces: u8) {}
- 나머지 케이스를 처리할수 있는 다른 방법으로는 _ 를 사용하는 방법도 있다. other 와 다른점은 해당값을 이용해서 처리할 필요가 없는 경우 더 간략하게 사용할수있다라는 차이가 있다.
- 케이스에서 아무처리도 안해줘도 되는 경우에는 () 로만 표현해줘도 되고 이는 특정 케이스에서만 처리해주고 나머지는 처리하지 않아도 될때 사용할수있다.
let dice_roll = 9; match dice_roll { 3 => add_fancy_hat(), 7 => remove_fancy_hat(), _ => reroll(), } match dice_roll { 3 => add_fancy_hat(), 7 => remove_fancy_hat(), _ => (), }
- 만약에 위와같이 특정케이스에서만 처리가 필요하고 나머지 케이스에서는 처리가 필요하지 않은 경우 if let 키워드를 이용해 같은내용이지만 단축해서 사용할수 있다.
let config_max = Some(3u8); match config_max { Some(max) => println!("The maximum is configured to be {}", max), _ => (), } let config_max = Some(3u8); if let Some(max) = config_max { println!("The maximum is configured to be {}", max); }
- if let 키워드는 else 도 같이 사용할수 있으며 이는 _ 의 사용과 의미는 동일하다.
let mut count = 0; match coin { Coin::Quarter(state) => println!("State quarter from {:?}!", state), _ => count += 1, } let mut count = 0; if let Coin::Quarter(state) = coin { println!("State quarter from {:?}!", state); } else { count += 1; }
'rust' 카테고리의 다른 글
[Rust] collection(1)-vector (0) 2023.02.06 [Rust] 7. 모듈시스템에 대하여 (0) 2023.02.05 [Defi] 디파이 시작해보기(1) (0) 2023.02.01 [Rust] 5. struct에 대하여 (0) 2023.01.31 [Rust] 4.ownership(3). slice (0) 2023.01.28