6 Enum and Pattern Matching
In this chapter, weโll look at enumerations, also referred to as enums. Enums allow you to define a type by enumerating its possible variants ๊ฐ๋ฅํ ์ํ์ ๋ชฉ๋ก์ ์ด๊ฑฐํ์ฌ ํ์ ์ ์ ์ํ๋ค๋ ์ ์๊ฐ ๋ง์์ ๋ ๋ค. ๋ณดํต ์๋์ ์ผ๋ก ์๋ก์ด ์ธ์ด๋ค์ด ๋ช ์์ ์ด๋ฉด์ ๊ฒฝ์ ์ ์ด๋ฉด์ ์์ ๋ฌธ๋ฒ์ ์ ๊ณตํ๋๋ฐ ๋ฌ์คํธ์ enum์ด ํนํ ๊ทธ๋ฐ ๋๋์ด๋ค.
6.1 Defining an Enum
- ๊ตฌ์กฐ์ฒด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃนํ ํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค๋ฉด, enum์ ํน์ ํ ๊ฐ์ด ๊ฐ์ง์ ์๋ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฐ์ ์ ์ํ๋ค.
์ด๋ฐ ๋ฅ์ ์ ์๊ฐ ์ข์ ๊ฒ ๊ฐ๋ค. ์ฒ์ Generic์ ๋ฐฐ์ธ ๋ ์ฒ์์ ๋ณต์กํ๊ณ ์ฝ๊ธฐ ์ด๋ ค์ด ๋ฌธ๋ฒ๊ณผ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ํฌ์ปค์ค๋ฅผ ํ๊ณ ๊ณต๋ถํ๋ ์ดํด๊ฐ ์๋์๋๋ฐ, ๋๊ฐ์ ๋ก์ง์ ์ฌ๋ฌ๋ฒ ์์ฑํ์ง ์๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ฌธ๋ฒ์ด๋ผ๊ณ c++ primer plus ์ฑ ์์ ์ค๋ช ์ ํด์ค์ ํด๋น ๊ด์ ์ผ๋ก ์ดํดํ๋ ค ํ๋ ์ดํด๊ฐ ์ ๋์์๋ ๊ธฐ์ต์ด ๋๋ค.
-
๊ณต์ ๊ฐ์ด๋์์๋ IP ์ฃผ์๋ฅผ ๋ค๋ฃจ๋ ์์ ๋ฅผ ๋ค๊ณ ์๋ค. IP์ฃผ์๋ผ๋ ๊ฐ๋ ์ ์ฝ๋๋ก ‘ํํ’ํ๋ค๋ฉด
- 4๊ฐ์ 8๋นํธ ์ซ์๋ก ๊ตฌ์ฑ๋ IPv4 ์ฃผ์๋ฅผ ๋ค๋ฃจ๋ ๊ฒฝ์ฐ
- 8๊ฐ์ 16๋นํธ ์ซ์๋ก ๊ตฌ์ฑ๋ IPv6 ์ฃผ์๋ฅผ ๋ค๋ฃจ๋ ๊ฒฝ์ฐ
-
์ด๋ ๊ฒ ๋๊ฐ์ง ์ํ๋ง ์กด์ฌํ๊ณ , ๋ชจ๋ IP์ ๋ฒ์ ์ ๋๊ฐ์ง ์ค ํ๋์ ์ํ๊ฒ ๋๋ค.
-
IP ์ฃผ์์ด๋ฉด์ ์ ๋๊ฐ์ง์ ์ํ๊ฐ ์๋ ๋ค๋ฅธ ์ํ์ ์ํ ์ ์๊ณ , ๋ ๋ค์ ์ํ ์ ์์ผ๋ฉฐ, ์ด๋ฐ ๊ฒฝ์ฐ์ enum์ ์ด์ฉํด์ ํํํ ์ ์๋ค.
-
๋ฒ์ 4์ ๋ฒ์ 6 ์ฃผ์ ๋ชจ๋ ๊ทผ๋ณธ์ ์ผ๋ก๋ IP ์ฃผ์์ด๋ฏ๋ก, ์ฝ๋๊ฐ ์ด๋ค ์ข ๋ฅ์ IP ์ฃผ์์๋ ์ ์ฉ๋๋ ์ํฉ์ ์ฒ๋ฆฌํ ๋ ๋์ผํ ํ์ ์ผ๋ก ์ทจ๊ธ๋์ด์ผ ํ๋ค.
-
์ฆ ๋ชจ๋ , ๊ณ ์ ํ, ๊ฐ๋ฅํ ์ํ์ ์ด๊ฑฐ์ด๋ฏ๋ก ์ผ์ ์ ๋์ ์ถ์ํ์ ์ญํ ์ ํ๋ค.
enum IpAddrKind {
V4,
V6,
}
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
fn route(ip_kind: IpAddrKind) {}
route(IpAddrKind::V4);
route(IpAddrKind::V6);
-
๋ฌธ๋ฒ์ enum ํค์๋๋ก ์์ํ๊ณ , ๊ฐ ์ํ๋ ์ค๊ดํธ๋ก ๋ฌถ์ธ ๋ชฉ๋ก์ผ๋ก ์ ์๋๋ค.
-
๊ฐ ์ํ๋ ๊ทธ ์์ฒด๋ก ์ ํจํ ๊ฐ์ด๋ค. ์ด ๊ฐ์ enum์ ์ด๋ฆ์ ํตํด ์ ๊ทผํ ์ ์๋ค.
-
enum์ ์ด๋ฆ๊ณผ ์ํ์ ์ด๋ฆ์ ๊ฐ์ ์ด๋ฆ ๊ณต๊ฐ์ ์์ผ๋ฏ๋ก, enum์ ์ด๋ฆ์ ํตํด ์ํ๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
-
enum์ ๊ฐ์ ์ ์ฅํ ์๋ ์๋ค.
enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
- ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ํ๊ฐ ๋ค๋ฅธ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ์ ์๋ค.
- ๋จ์ํ ์ด๊ฑฐํ์ String์ ๋งคํํ๋ ์ ๋๊ฐ ์๋๋ผ ์๋์ ๊ฐ์ ๊ฒ๋ค๋ ๊ฐ๋ฅํ๋ค.
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
- ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ํ๊ฐ ๋ค๋ฅธ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ์ ์๋ค.
struct Ipv4Addr {
// --snip--
}
struct Ipv6Addr {
// --snip--
}
enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
- ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ํ๊ฐ ๋ค๋ฅธ ๊ตฌ์กฐ์ฒด๋ฅผ ๊ฐ์ง ์ ์๋ค.
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
- ๋ค์ํ ๊ฒ๋ค์ ๋งคํํ๋, ํ๋์ enumerate variants์ ๊ฐ์ ํ์ ์ด ์๋ ๊ฒ๋ค์ ๋งคํํ ์ ์๋ค.
struct QuitMessage; // unit struct
struct MoveMessage {
x: i32,
y: i32,
}
struct WriteMessage(String); // tuple struct
struct ChangeColorMessage(i32, i32, i32); // tuple struct
impl Message {
fn call(&self) {
// method body would be defined here
}
}
let m = Message::Write(String::from("hello"));
m.call();
- impl๋ก ๋ฉ์๋๋ฅผ ์ ์ํ ์ ์๋ค.
6.1.1 The Option Enum and Its Advantages Over Null Values
-
Option<T>
๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์๋ enum์ด๋ค. -
Option<T>
๋Some(T)
์None
๋๊ฐ์ง ์ํ๋ฅผ ๊ฐ์ง๋ค. -
Option<T>
๋ null ๊ฐ์ ๋์์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. -
Java์ Optional๊ณผ ๋น์ทํ ๊ฐ๋ ์ด๋ค.
-
๊ฐ์ด ์๋ ๊ฒฝ์ฐ, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ(๊ทธ ๋ชจ๋
variant
) ๊ฐ ์๊ณ , ๊ทธ ๋ชจ๋ ์ผ์ด์ค๋ฅผ ๋ค๋ค์ผํ๋๋ฐ, Option์ ์ฌ์ฉํ๋ฉด ์ ํํ ๋ชจ๋ ์ผ์ด์ค๋ฅผ ํธ๋ค๋ง ํ๋์ง, ์ปดํ์ผ๋ฌ๊ฐ ์ฒดํฌํด์ค๋ค. -
์ฐ๋ฆฌ๋ ์ธ์ด๋ฅผ ๋ฐฐ์ธ๋, ํด๋น ์ธ์ด๊ฐ ์ด๋ ํ ๊ธฐ๋ฅ์ ํฌํจ(include)ํ๊ณ ์๋์ง์๋ ์ถฉ๋ถํ ์ฃผ๋ชฉํ๋ฉด์, ์ด๋ ํ ๊ธฐ๋ฅ์ ๋ฐฐ์ (exclude)ํ๊ณ ์๋์ง์๋ ์ถฉ๋ถํ ์ฃผ๋ชฉํ์ง ์๋๋ค.
-
๊ธฐ๋ฅ์ ๋ฐฐ์ ๋ํ ์ธ์ด์ ํน์ง์ด๋ผ๋ ์ ์ ์์ ์์ ๊ฐ์กฐํ๊ณ ์๋ค.
-
๊ฒฐ๋ก ์ ์ผ๋ก Rust๋ null์ ์ ๊ณตํ์ง ์๋๋ค. null์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ธ์ด์ ๋ชจ๋ ๊ฐ์ ๋๊ฐ์ง variant๋ฅผ ๊ฐ์ง๋ค. (
null
,not null
)
Tony Hoare๊ฐ null์ ๋ฐ๋ช ํ๋๋ฐ, ํ์ ์ด๊ฒ์ด ‘my billion dollar mistake’๋ผ๊ณ ๋งํ๋ค.
๊ณต์ ๊ฐ์ด๋ ๋ฌธ์์์ ํด๋น ๋ด์ฉ๊ณผ ๊ด๋ จํ ์ธํฐ๋ทฐ ๊ธฐ์ฌ๋ฅผ ์ธ์ฉํ๊ณ ์๋๋ฐ, ์ด๊ฒ ๋์ถฉ 60๋ ๋ง์ ์ฌ๊ณผ๋ผ๊ณ ํ๋ค. ํด๋น ๊ธฐ์ฌ์ ๋ฐฐ์คํธ ๋๊ธ์๋, “Bjarne Stroustrup์ ์ฌ๊ณผ๊น์ง๋ 14๋ ์ด ๋ ๋จ์๋ค” ๋ผ๋ ๋๊ธ์ด ๋ฌ๋ ค ์์ด ๊ฒ์ํด๋ดค๋๋ฐ, 1979๋ ์ cpp์ ํ์๋ ์ด์๋ค.
- ๋ฌดํผ ์ค์ ๊ตฌํ์ ์๋์ ๊ฐ๋ค.
enum Option<T> {
None,
Some(T),
}
-
prelude์๋ Option์ด ํฌํจ๋์ด ์์ด์(๊ทธ๋งํผ ์ ์ฉํ๊ณ ์์ฃผ ์ฌ์ฉํด์ผ ํ๊ธฐ์) ๋ฐ๋ก includeํ ํ์๊ฐ ์๊ณ , Option์ ์ฌ์ฉํ ๋๋
Option::
์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค. -
Some<T>
๋ ์ ๋ค๋ฆญ์ผ๋ก ํน์ ํ์ ์ ๊ฐ์ง ์ ์๋ค.
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
-
some_number์ ํ์ ์
Option<i32>
์ด๋ค. -
some_string์ ํ์ ์
Option<&str>
์ด๋ค. -
absent_number์ ํ์ ์
Option<i32>
์ด๋ค. -
๋ฌดํผ ๊ฒฐ๋ก ์ ์ผ๋ก
Some
value๋ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ๋ํ๋ด๊ณ ,None
value๋ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ๋ํ๋ธ๋ค. -
None
variant๋ ์ฌ์ค์ null๊ณผ ๊ฐ์ ์๋ฏธ๋ฅผ ์ง๋๋๋ฐ, ๊ตณ์ด ์ด๋ ๊ฒ ํ๋ ์ด์ ๋ ๋ญ๊น? (์null
๋ณด๋คNone
์ ์ฌ์ฉํ๋๊ฐ?) -
์งง๊ฒ ์์ฝํ๋ฉด,
Option<T>
์T
๋ ๋ค๋ฅธ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ๋ฌ๋Option<T>
๋ฅผ ์ฌ์ฉ ํ ๋, ๋ฌด์กฐ๊ฑด์ ์ผ๋ก valid value๋ผ๊ณ ์์ ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
let x: i8 = 5;
let y: Option<i8> = Some(5);
let sum = x + y;
-
์ ์ฝ๋๋ ์ปดํ์ผ ๋์ง ์๋๋ค.
Option<i8>
์i8
์ ๋ค๋ฅธ ํ์ ์ด๊ธฐ ๋๋ฌธ์ด๋ค. -
๋น์ฐํ๊ฒ๋
i8
๊ณผi8
์ด ์๋ ๋ฌด์์ธ๊ฐ์ ๊ฐ์ ๋ํ๋ ๋ฐฉ๋ฒ์ ์์ง ๋ชปํ๋ค. -
์ปดํ์ผ๋ฌ๊ฐ ์ดํด ํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด์๋,
Option<i8>
๋ฅผ ๊ทธ๋ฅ ์ฌ์ฉํ๋๊ฒ์ด ์๋ ๋ฌด์์ธ๊ฐ์ ์ฒ๋ฆฌ๋ฅผ ํด์ผํ๋ค. -
์ฌ๊ธฐ์ ๋ฌด์์ธ๊ฐ์ ์ฒ๋ฆฌ๋ ๋ฐ๋ก
Option
์ variants๋ฅผ ๋ค๋ค์ผ ํ๋ ๊ฒ์ด๊ณ , ๊ทธ๋ฌํ ๊ณผ์ ์ดํ์ null(None) ์ ๋ํ ๋์์ ์งํํ๊ฒ๋๋ค.
6.2 The match
Control Flow Construct
-
match
๋ ๋ค๋ฅธ ์ธ์ด์switch
์ ๋น์ทํ ์ญํ ์ ํ๋ค. -
Pattern์ literal value, variable, wild card, tuple, destructured structure, enum ๋ฑ์ ํฌํจํ ์ ์๋ค.
-
match
๋ ์ปดํ์ผ๋ฌ๋ก ํ์ฌ๊ธ ๋ชจ๋ ์ผ์ด์ค๋ฅผ ๋ค๋ฃจ๋์ง ํ์ธํ๊ฒ ํ๋ค. -
๋์ ์ํ๊ธฐ์ฒ๋ผ ์ฒ์์ผ๋ก ์ผ์นํ๋ ํจํด์ ๋ง๋๋ฉด ํด๋น ๋ธ๋ก์ ์คํํ๊ณ , ๋๋จธ์ง๋ ๋ฌด์ํ๋ค.
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,
}
}
-
if ๋ฌธ๊ณผ ๋ค๋ฅธ ์ ์ ๊ตณ์ด
boolean
์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค๋ ์ ์ด๋ค. -
match
์ arm์ด๋=>
๊ณผ,
๋ก ๊ตฌ๋ถ๋ ํจํด๊ณผ ์คํ ์ฝ๋ ๋ธ๋ก์ด๋ค. ํจํด๊ณผ ์ฝ๋ ๋ธ๋ก์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. -
๊ฐ๊ฐ์ arm์ ์ฐ๊ด๋์ด์๋ ์ฝ๋ ๋ธ๋ก์ ํํ์์ด๋ฉฐ, ์ด ํํ์์ ๊ฒฐ๊ณผ๋
match
ํํ์์ ๊ฒฐ๊ณผ๊ฐ ๋๋ค. -
ํ ์ค์ ๋๋ ์ฝ๋๋ฅผ ์์ฑํ ๋๋
{}
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
6.2.1 Patterns That Bind to Values
match
์ ๋ ๋ค๋ฅธ ์ ์ฉํ ๊ธฐ๋ฅ์ ํจํด์ ๋งค์นญ๋๋ ๊ฐ์ ๋ฐ์ธ๋ฉ ํ ์ ์๋ค๋ ๊ฒ์ด๊ณ , enumd variants ์ ๊ฐ์ ์ถ์ถํ ์ ์๋ค.
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
Quarter
variant๋UsState
๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
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
},
}
}
-
Coin::Quarter(state)
์์state
๋UsState
ํ์ ์ด ๋๋ค.\ -
์ด๋ ๊ฒ ํ๋ฉด
UsState
๋ฅผ ์ถ์ถํ ์ ์๋ค.
6.2.2 Matching with Option
Option<T>
๋ฅผ ์ฌ์ฉํ ๋๋match
๋ฅผ ์ฌ์ฉํ๋ ์์ .
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
-
match
rust์ ์ ์ฐํ enum๊ณผ ํจ๊ป ์ฌ์ฉํ ๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ๋๋ค. -
match
์ variable binding ๊ธฐ๋ฅ ๋์ ์ฝ๋๊ฐ ๊น๋ํ๊ฒ ๋จ์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ , ์ค์ ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์๋ ์ด์ ์ ๋๋ ์ ์๋ค.
6.3.3 Mathches Are Exhaustive
match
๋ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๋ค๋ฃจ์ง ์์ผ๋ฉด ์ปดํ์ผ ๋์ง ์๋๋ค.
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
Some(i) => Some(i + 1),
}
}
-
์ ์ฝ๋๋ ์ปดํ์ผ ๋์ง ์๋๋ค.
None
์ ๋ํ ์ฒ๋ฆฌ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค. -
์ด์ฒ๋ผ ๋ฌ์คํธ์
match
๋ ์ฒ ์ ํ๊ธฐ ๋๋ฌธ์ ์ผ์ด๋ ์ ์๋ ์ค์๋ฅผ ๋ฐฉ์งํด์ค๋ค.
billion dollor mistake๋ ์ ์ด์ ๋ฌ์คํธ์์ ๊ฐ๋ฅํ์ง ์๋ค๊ณ ํ ๋ฒ ๋ ๋น๊ผฐ๋ค ใ ใ
6.3.4 Catch-all Patterns and The _
Placeholder
- enum๊ณผ
match
๋ฅผ ์ฌ์ฉํ ๋, ํน์ ๊ฐ์ ๋ํด์๋ง ํน๋ณํ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ , ๋๋จธ์ง์ ๋ํด์๋ ์์ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์ ๋๊ฐ ์๋ค.
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) {}
-
์ด๋ฌํ ๊ฒฝ์ฐ 3,7์ด ์๋ ๋ชจ๋ ๊ฒฝ์ฐ๋
other
์ ๋งค์นญ๋์ด ์ฒ๋ฆฌ๋๋ค. -
์ฐธ๊ณ ๋ก ๋ค๋ฅธ ์ธ์ด์
switch
์์์ ๊ฐ์ด other์ ์์ ์ฐ๋ฉด ๊ทธ ์๋ arm๋ค์ ๋น๊ต์กฐ์ฐจ ์ํ๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ ํ์ํ๋ค. -
๋น์ทํ๊ฒ catch-all ํ๋ฉด์๋, ํด๋น ๊ฐ์ ๋ํด์๋ ์๋ฌด๊ฒ๋ ํ์ง ์์ ๋๋
_
๋ฅผ ์ฌ์ฉํ๋ค.
let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
_ => (), // or another actions for now do nothing
}
fn add_fancy_hat() {}
fn remove_fancy_hat() {}
6.4 Concise Control Flow with if let
if let
์ ์ฌ์ฉํ๋ฉด, ํ๋์ ๊ฐใ ์ ๋ํด์๋ง ๋งค์นญ์ ํ๊ณ , ๋๋จธ์ง๋ฅผ ๋ฌด์ํ๋ ๊ฒฝ์ฐ์match
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๊ฐ๊ฒฐํ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
if let Some(3) = some_u8_value {
println!("three");
}
-
๋ ์ฝ๋ ๋ชจ๋ ์ ํํ ๊ฐ์ ๋์์ ํ๋ค.
-
if let
์ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ๋, verboseํ ์ฝ๋๋, ๊ตณ์ด ํ์์๋ ๋ค์ฌ์ฐ๊ธฐ๋ ์์ ์ฃผ์ง๋ง,match
์ exhaustive checking์ ์ ๊ณตํ์ง ์๋๋ค. -
๊ฒฐ๋ก ์ ์ผ๋ก syntax sugar์ด๋ค.
-
else๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค.
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
6.5 Summary
๋ค์ํ match ์ฌ์ฉ ์์
// 1. ํธ๋ํฝ ๋ผ์ดํธ ์๋ฎฌ๋ ์ดํฐ
enum TrafficLight {
Red,
Yellow,
Green,
}
fn simulate_traffic_light(light: TrafficLight) {
match light {
TrafficLight::Red => println!("Stop"),
TrafficLight::Yellow => println!("Caution"),
TrafficLight::Green => println!("Go"),
}
}
// 2. ํ์ผ ์ฝ๊ธฐ ํจ์
use std::fs;
fn read_file(file_path: &str) -> Result<String, String> {
match fs::read_to_string(file_path) {
Ok(contents) => Ok(contents),
Err(_) => Err(String::from("Failed to read the file.")),
}
}
// 3. ๋๋ฌผ์ ์๋ฆฌ ์ถ๋ ฅ
enum Animal {
Dog,
Cat,
Bird,
}
fn make_sound(animal: Animal) {
match animal {
Animal::Dog => println!("Woof!"),
Animal::Cat => println!("Meow!"),
Animal::Bird => println!("Tweet!"),
}
}
// 4. ๋ชจ์์ ๋ฉด์ ๊ณ์ฐ
enum Shape {
Circle(f64),
Triangle(f64, f64),
Rectangle(f64, f64),
}
fn calculate_area(shape: Shape) -> f64 {
match shape {
Shape::Circle(radius) => std::f64::consts::PI * radius * radius,
Shape::Triangle(base, height) => 0.5 * base * height,
Shape::Rectangle(width, height) => width * height,
}
}
// 5. ์ฃผ์ ์ ๋ณด ์ถ๋ ฅ
enum Address {
City(String),
State(String),
Country(String),
}
struct Location {
city: String,
state: String,
country: String,
}
fn print_city_address(address: Address) {
match address {
Address::City(city) => println!("City: {}", city),
_ => (),
}
}
// 6. ๋ ์ต์
์ฒ๋ฆฌ
enum OptionEnum<T> {
Some(T),
None,
}
fn process_option(option1: OptionEnum<i32>, option2: OptionEnum<i32>) {
match (option1, option2) {
(OptionEnum::Some(val1), OptionEnum::Some(val2)) => println!("Both options have values: {}, {}", val1, val2),
_ => println!("At least one option is None."),
}
}
// 7. ์ฌ์น์ฐ์ฐ ํจ์
fn calculate_operation(op: &str, num1: f64, num2: f64) -> Result<f64, String> {
match op {
"+" => Ok(num1 + num2),
"-" => Ok(num1 - num2),
"*" => Ok(num1 * num2),
"/" => {
if num2 == 0.0 {
Err(String::from("Division by zero is not allowed."))
} else {
Ok(num1 / num2)
}
},
_ => Err(String::from("Invalid operation.")),
}
}
// 8. ๊ณ์ ์ถ๋ ฅ
enum Season {
Spring,
Summer,
Autumn,
Winter,
}
fn print_season_message(season: Season) {
match season {
Season::Spring => println!("It's spring!"),
Season::Summer => println!("It's summer!"),
Season::Autumn => println!("It's autumn!"),
Season::Winter => println!("It's winter!"),
}
}
// 9. ๋ก๊ทธ์ธ ํจ์
fn login(username: &str, password: &str) -> Result<(), String> {
if password == "correctpassword" {
Ok(())
} else {
Err(String::from("Incorrect password."))
}
}
// 10. ์ฃผ๋ฌธ ์ํ ์ถ๋ ฅ
enum OrderStatus {
Pending,
Completed,
}
fn print_order_status(status: OrderStatus) {
match status {
OrderStatus::Pending => println!("Your order is pending."),
OrderStatus::Completed => println!("Your order is completed."),
}
}