본문 바로가기

Rust

[Rust] Option 과 Result

 

Option

러스트에는 기본적으로 null이 존재하지 않습니다. 하지만 null을 표현하기 위한 방법으로 Option이 존재합니다.

enum Option<T> {
    Some(T),
    None,
}

let x = Some(7);
let y = None;

enum으로 Option을 정의하며 T는 제네릭 타입으로 어떤 데이터 타입도 가능합니다.

따로 만들어 줄 필요 없이 기본 라이브러리에 저장되어 있습니다.

fn main() {
    let some_number = Some(5);
    let some_string = Some("a string");
    println!("some_number : {}",some_number.unwrap());
    println!("some_string : {}", some_string.unwrap());


}

위와 같이 sum_number와 some_string에는 정수와 문자열을 저장하였습니다.

위 코드에서 변수의 값을 출력할 때 unwarp을 사용하였는데 그 이유는 Some으로 감싸인 값을 사용하기 위해서입니다.

 

Result

프로그램에서 대부분의 에러는 프로그램을 전부 멈추도록 요구될 정도로 심각하지는 않습니다. 함수가 실행된 결과로 인해 발생할 수 있는 에러에 대응하기 위해 Result를 사용합니다. 

enum Result<T, E> {
    Ok(T),
    Err(E),
}

 

Option과 비슷하게 정의되어 있습니다. T와 E는 제네릭 타입니다.

use std::fs::File;

fn main() {
    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => {
            panic!("There was a problem opening the file: {:?}", error)
        },
    };
}

hello.txt라는 파일이 정상적으로 열린다면 file을 반환하고 파일을 여는데 실패한다면 panic을 발생시킵니다.

실행 결과

실행시킨 디렉토리에 hello.txt라는 파일이 존재하지 않기 때문에 "There was a problem opening the file..."이 출력되며 패닉 된 것을 확인할 수 있습니다. 

 

use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(ref error) if error.kind() == ErrorKind::NotFound => {
            match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => {
                    panic!(
                        "Tried to create file but there was a problem: {:?}",
                        e
                    )
                },
            }
        },
        Err(error) => {
            panic!(
                "There was a problem opening the file: {:?}",
                error
            )
        },
    };
}

처음의 방법은 어떠한 이유에서든 에러가 발생하면 같은 panic을 발생시킬 것입니다. 만약 파일이 존재하지 않는다면 새로운 파일을 생성하고 그 밖에 다른 이유로 발생한 에러는 패닉을 발생시키도록 error.kind()를 통해 다른 종류의 에러들을 제어할 수 있습니다.

 

unwarp & expect

match를 활용한 대응에서 코드가 길어지고 의도를 항상 잘 전달하는 것은 아니기 떄문에 unwarp과 expect라는 헬퍼 메소드를 통해 간결한 작업이 가능합니다. 

use std::fs::File;

fn main() {
    let f = File::open("hello.txt").unwrap();
}

hello.txt 파일이 없는 상태에서 이 코드를 실행시키면, unwrap은 에러가 없다면 Ok의 값을 반환할 것이며 아니라면 panic을 발생시킬 것입니다. 

use std::fs::File;

fn main() {
    let f = File::open("hello.txt").expect("Failed to open hello.txt");
}

expect는 panic이 발생할 때 메시지를 지정할 수 있게 해줍니다. 

'Rust' 카테고리의 다른 글

[Rust] 해쉬맵 (hash map)  (0) 2022.04.26
[Rust] 문자열  (0) 2022.04.25
[Rust] match 흐름 제어 연산자  (0) 2022.04.24
[Rust] enum 열거형  (0) 2022.04.23
[Rust] 구조체의 메소드  (0) 2022.04.22