Rust : Option 처리

  • Rust 사용하면서 필수적인 Option 에 대해 정리하며, Option 처리 하는 방법에 대해 코드를 작성합니다.
  • 주의 : 공부하는 과정에서 정리한 문서이므로 부정확할 수 있으며, 수시로 내용 업데이트합니다.

Option

Option 처리하기

match

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn match_some_1(option: Option<i32>) -> bool {
match option {
Some(val) => {
if val == 1 {
return true;
} else {
return false;
}
}
None => return false,
};
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_match_some_1() {
assert!(match_some_1(Some(1)));
assert!(!match_some_1(Some(2)));
assert!(!match_some_1(None));
}
}


1인 경우에만 true를 그 외의 경우는 false 를 리턴하도록 합니다.
테스트해보니 잘 동작하네요.
하지만 매번 저렇게 match를 다 하면 코드가 장황해지겠죠.

unwrap과 expect

  • 참고 : 에러가 났을 때 패닉을 위한 숏컷: unwrap과 expect
  • 먼저 unwrap입니다. 말 그대로 Option을 벗겨줍니다.
  • expect 는 어떤 에러인지 사용자 텍스트를 print할 뿐 unwrap과 동일합니다.
  • 문제는 None일 경우에 panic을 일으키고 프로그램을 중단시킵니다.
    간단한 프로그램에서야 관계없지만 큰 프로젝트에서는 문제가 되죠.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn unwrap_some_1(option: Option<i32>) -> bool {
let val = option.unwrap();
if val == 1 {
return true;
} else {
return false;
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_unwrap_some_1() {
assert!(unwrap_some_1(Some(1)));
assert!(!unwrap_some_1(Some(2)));
assert!(!unwrap_some_1(None));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

% cargo test
Finished test [unoptimized + debuginfo] target(s) in 0.00s
Running unittests src/lib.rs (target/debug/deps/rust_test-1b20918bc1a6980b)

running 2 tests
test test::test_match_some_1 ... ok
test test::test_unwrap_some_1 ... FAILED

failures:

---- test::test_unwrap_some_1 stdout ----
thread 'test::test_unwrap_some_1' panicked at 'called `Option::unwrap()` on a `None` value', src/lib.rs:15:22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
test::test_unwrap_some_1

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--lib`

if let 으로 단일 처리하기

  • 참고 : if let을 사용한 간결한 흐름 제어
  • match는 모든 case 에 대해서 처리해야해서 코드가 단단해지는 장점이 있지만, 코드가 장황해지는 단점또한 있습니다.
  • if let 은 단일 상황에 대해서 간결히 처리할 수 있는 장점이 있습니다.
  • 아래 if_let_some_1 는 위의 match_some_1 와 비교하면 많이 간결해진 것을 확인할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn if_let_some_1(option: Option<i32>) -> bool {
if let Some(1) = option {
return true;
} else {
return false;
}
}
#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_if_let_some_1() {
assert!(if_let_some_1(Some(1)));
assert!(!if_let_some_1(Some(2)));
assert!(!if_let_some_1(None));
}
}
Share