IT’s Portfolio

[Rust] Start Rust (Day 18) - Error Handling λ³Έλ¬Έ

Development Study/Rust

[Rust] Start Rust (Day 18) - Error Handling

f1r3_r41n 2023. 3. 9. 12:56
728x90
λ°˜μ‘ν˜•

πŸ¦€ Rust Day 18

🏳️ Error Handling

  • λŸ¬μŠ€νŠΈλŠ” μ—λŸ¬μ˜ λ°œμƒ κ°€λŠ₯성을 μΈμ§€ν•˜κ³  κ°œλ°œμžκ°€ μ½”λ“œλ₯Ό μ»΄νŒŒμΌν•˜κΈ° 전에 μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•˜λ„λ‘ μœ λ„ν•¨
  • λŒ€λΆ€λΆ„ μ–Έμ–΄λŠ” μ—λŸ¬λ₯Ό κ΅¬λΆ„ν•˜μ§€ μ•Šκ³  μ˜ˆμ™Έ(exception) 같은 λ©”μ»€λ‹ˆμ¦˜μ„ μ΄μš©ν•΄ λ˜‘κ°™μ΄ μ²˜λ¦¬ν•¨
  • λŸ¬μŠ€νŠΈμ— μ˜ˆμ™ΈλΌλŠ” κ°œλ…μ€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©°, μ—λŸ¬λ₯Ό 두 κ°€μ§€λ‘œ κ΅¬λΆ„ν•˜κ³  있음
  • 회볡 κ°€λŠ₯ν•œ μ—λŸ¬(recoverable error)
    • μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 파일 λ“± 회볡 κ°€λŠ₯ν•œ μ—λŸ¬λŠ” μ‚¬μš©μžμ—κ²Œ 문제λ₯Ό λ³΄κ³ ν•˜κ³  μž‘μ—…μ„ λ‹€μ‹œ μ‹œλ„ν•˜λ„λ‘ μš”μ²­ν•  수 있음
    • Result<T, E> νƒ€μž…μœΌλ‘œ ν‘œν˜„
  • 회볡이 λΆˆκ°€λŠ₯ν•œ μ—λŸ¬(unrecoverable error)
    • 회볡 λΆˆκ°€λŠ₯ν•œ μ—λŸ¬λŠ” λ°°μ—΄μ˜ λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜λŠ” λ©”λͺ¨λ¦¬μ— λŒ€ν•œ μ ‘κ·Όμ²˜λŸΌ 항상 λ²„κ·Έμ˜ κ°€λŠ₯성을 λ‚΄ν¬ν•˜κ³  있음
    • ν•΄λ‹Ή μ—λŸ¬κ°€ λ°œμƒν•œ ν”„λ‘œκ·Έλž¨μ€ panic! 맀크둜λ₯Ό λ°”μΈλ”©ν•˜λ©° 싀행을 μ’…λ£Œν•¨

 

1️⃣ panic! 맀크둜λ₯Ό μ΄μš©ν•œ 회볡 λΆˆκ°€λŠ₯ν•œ μ—λŸ¬ 처리

  • νŒ¨λ‹‰μ€ λŒ€λΆ€λΆ„ μ–΄λ–€ μ’…λ₯˜μ˜ 버그가 λ°œκ²¬λ˜μ—ˆλŠ”λ° κ°œλ°œμžκ°€ 이 μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•  방법이 λ§ˆλ•…μΉ˜ μ•Šμ„ λ•Œ ν™œμš©
  • panic! 맀크둜λ₯Ό μ‹€ν–‰ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ€ μ‹€νŒ¨ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•˜κ³ , μŠ€νƒμ„ λͺ¨λ‘ μ •λ¦¬ν•œ λ‹€μŒ μ’…λ£Œν•¨
  • νŒ¨λ‹‰μ΄ λ°œμƒν–ˆμ„ λ•Œ μŠ€νƒμ„ ν’€μ–΄μ£Όκ±°λ‚˜(unwind) μ·¨μ†Œν•˜κΈ°
    • 기본적으둜 νŒ¨λ‹‰μ΄ λ°œμƒν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ€ μŠ€νƒμ„ ν’€κΈ° μ‹œμž‘
      • μ—­μˆœμœΌλ‘œ μˆœνšŒν•˜λ©° 각 ν•¨μˆ˜μ— μ „λ‹¬λ˜μ—ˆλ˜ 데이터 정리
      • 이λ₯Ό μœ„ν•΄ μ‹€ν–‰λ˜λŠ” μž‘μ—…μ˜ 양은 상당함
    • μŠ€νƒμ„ μ¦‰μ‹œ μ·¨μ†Œν•΄μ„œ μŠ€νƒμ„ μ •λ¦¬ν•˜μ§€ μ•Šκ³  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ’…λ£Œν•˜λŠ” 방법
      • ν”„λ‘œκ·Έλž¨μ΄ μ‚¬μš©ν•˜λ˜ λ©”λͺ¨λ¦¬λŠ” OSκ°€ 정리해야 함
      • ν”„λ‘œκ·Έλž¨μ˜ λ°”μ΄λ„ˆλ¦¬ 파일의 크기λ₯Ό μ΅œλŒ€ν•œ μž‘κ²Œ ν•΄μ•Ό ν•œλ‹€λ©΄ Cargo.toml 파일의 [profile] μ„Ήμ…˜μ— panic = 'abort' λ₯Ό μΆ”κ°€ν•˜λ©΄ μŠ€νƒμ„ 풀어주지 μ•Šκ³  μ·¨μ†Œν•  수 있음
      • 릴리즈 λͺ¨λ“œμ—μ„œ νŒ¨λ‹‰μ„ μ·¨μ†Œν•  μ‹œ
          [profile.release]
          panic = 'abort'
fn main() {
    panic!("Error!");
}
  • panic! 맀크둜λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ§ˆμ§€λ§‰ 두 쀄에 μ—λŸ¬ λ©”μ‹œμ§€κ°€ ν‘œμ‹œλ¨
  • 첫 번째 쀄에 νŒ¨λ‹‰ λ©”μ‹œμ§€μ™€ νŒ¨λ‹‰μ΄ λ°œμƒν•œ μ†ŒμŠ€ μ½”λ“œμ˜ μœ„μΉ˜κ°€ 좜λ ₯됨
  • src/main.rs:4:5 => src/main.rs 파일의 λ„€ 번째 쀄 λ„€ 번째 문자

πŸ€” panic! 역좔적 μ‚¬μš©ν•˜κΈ°

fn main() {
    let v = vec![1, 2, 3];

    v[99];
}
  • λ²‘ν„°μ˜ 크기λ₯Ό λ²—μ–΄λ‚˜λŠ” 인덱슀λ₯Ό μ΄μš©ν•΄ 값을 읽을 λ•Œ, panic! 맀크둜 호좜
  • C 같은 λ‹€λ₯Έ μ–Έμ–΄λŠ” 이런 경우 μ›μΉ˜ μ•Šλ˜ 값이라도 κ°œλ°œμžκ°€ μ§€μ •ν•œ μœ„μΉ˜μ˜ 값을 리턴함
    • 버퍼 μ˜€λ²„λ¦¬λ“œ(buffer overread)
      • 인덱슀둜 μ§€μ •ν•œ μœ„μΉ˜μ˜ λ©”λͺ¨λ¦¬κ°€ 벑터가 κ΄€λ¦¬ν•˜λŠ” λ©”λͺ¨λ¦¬κ°€ μ•„λ‹ˆλ”λΌλ„ 벑터에 μ €μž₯된 값에 ν•΄λ‹Ήν•˜λŠ” μœ„μΉ˜μ˜ λ©”λͺ¨λ¦¬μ— μ €μž₯된 값을 리턴함
      • κ³΅κ²©μžκ°€ ν•΄λ‹Ή λ°©λ²•μœΌλ‘œ 인덱슀λ₯Ό μ‘°μž‘ν•΄μ„œ μ½μ–΄μ„œλŠ” μ•ˆ λ˜λŠ” 값을 읽게 λ˜λŠ” λ³΄μ•ˆμƒμ˜ 취약점이 되기 쉬움
  • panic! λ§€ν¬λ‘œκ°€ λ°”μΈλ”©λœ μ‹€ν–‰ 결과에 μžˆλŠ” λ…ΈνŠΈμ—λŠ” RUST_BACKTRACE ν™˜κ²½ λ³€μˆ˜λ₯Ό μ΄μš©ν•΄ μ •ν™•νžˆ μ–΄λ–»κ²Œ μ—λŸ¬κ°€ λ°œμƒν–ˆλŠ”μ§€λ₯Ό 역좔적할 수 μžˆλ‹€λŠ” 것을 μ•Œλ €μ€Œ
    • 역좔적은 κ·Έ μ§€μ κΉŒμ§€ 호좜된 λͺ¨λ“  ν•¨μˆ˜μ˜ λͺ©λ‘
    • 제일 μœ„μ˜ ν•¨μˆ˜λΆ€ν„° μš°λ¦¬κ°€ μž‘μ„±ν•œ νŒŒμΌκΉŒμ§€ ν•¨μˆ˜μ˜ 호좜 과정을 μΆ”μ ν•˜λŠ” 것
  • 역좔적 정보λ₯Ό μ–»μœΌλ €λ©΄ 디버그 심볼(debug symbols) 이 ν™œμ„±ν™”λ˜μ–΄ μžˆμ–΄μ•Ό 함
    • cargo build λ‚˜ cargo run λͺ…령을 --release ν”Œλž˜κ·Έ 없이 μ‹€ν–‰ν•˜λ©΄ 기본적으둜 ν™œμ„±ν™”λ¨

 

2️⃣ Result νƒ€μž…μœΌλ‘œ μ—λŸ¬ μ²˜λ¦¬ν•˜κΈ°

  • λŒ€λΆ€λΆ„ μ—λŸ¬λŠ” ν”„λ‘œκ·Έλž¨μ„ μ™„μ „νžˆ μ’…λ£Œν•΄μ•Ό ν•  μ •λ„λ‘œ 치λͺ…μ μ΄μ§€λŠ” μ•ŠμŒ
enum Result<T, E> {
    Ok(T),
    Err(E),
}
  • Result μ—΄κ±°μž μ •μ˜ μ½”λ“œ
  • T 와 E λŠ” μ œλ„€λ¦­ νƒ€μž… λ§€κ°œλ³€μˆ˜
  • T λŠ” μž‘μ—…μ΄ μ„±κ³΅ν•œ 경우 Ok 열것값 μ•ˆμ— 포함될 κ°’μ˜ νƒ€μž…
  • E λŠ” μž‘μ—…μ΄ μ‹€νŒ¨ν•œ 경우 Err 열것값 μ•ˆμ— 포함될 κ°’μ˜ νƒ€μž…
use std::fs::File;

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

    let f = match f {
        Ok(file) => file,
        Err(error) => {
            panic!("File Open Error: {:?}", error);
        }
    };
}
  • match ν‘œν˜„μ‹μœΌλ‘œ Result νƒ€μž…μ˜ 리턴값을 μ œμ–΄ν•˜λŠ” μ½”λ“œ
  • Option μ—΄κ±°μžμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ Result μ—΄κ±°μžλ„ 프렐λ₯˜λ“œμ— μ˜ν•΄ μžλ™μœΌλ‘œ 좔가됨

πŸ€” match ν‘œν˜„μ‹μœΌλ‘œ μ—¬λŸ¬ μ’…λ₯˜μ˜ μ—λŸ¬ μ²˜λ¦¬ν•˜κΈ°

use std::{fs::File, io::ErrorKind};

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

    let f = match f {
        Ok(file) => file,
        Err(ref error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("File create error!: {:?}", e),
            },
            others => panic!("File open error!: {:?}", others),
        },
    };
}
  • μ€‘μ²©λœ match ν‘œν˜„μ‹μ„ μ΄μš©ν•΄ μ—λŸ¬μ˜ μ’…λ₯˜μ— 따라 λ‹€λ₯΄κ²Œ μ²˜λ¦¬ν•˜κΈ°
    • File::open λ©”μ„œλ“œκ°€ λ¦¬ν„΄ν•˜λŠ” Err 열것값에 μ €μž₯된 κ°’μ˜ νƒ€μž…μ€ io::Error νƒ€μž…
    • io::Error κ΅¬μ‘°μ²΄λŠ” io::ErrorKind νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” kind λ©”μ„œλ“œ 제곡
    • ErrorKind::NotFound : μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” νŒŒμΌμ„ μ—΄κ³ μž ν•  λ•Œ λ°œμƒν•˜λŠ” 열것값
    • error.kind() κ°€ λ¦¬ν„΄ν•œ 값이 ErrorKind::NotFound 열것값일 λ•Œ 파일 생성
    • 파일 생성이 μ‹€νŒ¨ν•  경우λ₯Ό λŒ€λΉ„ν•΄ match ν‘œν˜„μ‹μ— 가지λ₯Ό 좔가함
    • ErrorKind::NotFound μ—λŸ¬λ₯Ό μ œμ™Έν•œ λ‹€λ₯Έ μ—λŸ¬μΌ 경우 ν”„λ‘œκ·Έλž¨μ΄ νŒ¨λ‹‰μ— 빠짐

πŸ€” μ—λŸ¬ λ°œμƒ μ‹œ νŒ¨λ‹‰μ„ λ°œμƒν•˜λŠ” 더 λΉ λ₯Έ 방법: unwrap κ³Ό expect

  • Result<T, E> νƒ€μž…μ€ λ‹€μ–‘ν•œ μž‘μ—…μ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ unwrap λ©”μ„œλ“œμ™€ expect λ©”μ„œλ“œ 제곡
    • unwrap λ©”μ„œλ“œ
      • μ€‘μ²©λœ match ν‘œν˜„μ‹κ³Ό μ •ν™•νžˆ 같은 λ™μž‘μ„ ν•˜λŠ” 단좕(shortcut) λ©”μ„œλ“œ
      • Result νƒ€μž…μ΄ Ok 열것값일 λ•Œ Ok 열것값에 μ €μž₯된 κ°’ 리턴
      • Result νƒ€μž…μ΄ Err 열것값일 λ•ŒλŠ” panic! 맀크둜 호좜
    • expect λ©”μ„œλ“œ
      • unwrap λ©”μ„œλ“œμ™€ μœ μ‚¬ν•˜μ§€λ§Œ panic! λ§€ν¬λ‘œμ— μ—λŸ¬ λ©”μ‹œμ§€ 전달 κ°€λŠ₯
      • 개발자의 μ˜λ„λ₯Ό 더 λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•˜λŠ” λ™μ‹œμ— νŒ¨λ‹‰μ΄ λ°œμƒν•œ 원인을 더 μ‰½κ²Œ 좔적 κ°€λŠ₯

πŸ€” μ—λŸ¬ μ „νŒŒν•˜κΈ°

use std::io::{self, Read};
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = match File::open("hello.txt") {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut s = String::new();

    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

fn main() {
    println!("{:?}", read_username_from_file());
}
  • match ν‘œν˜„μ‹μ„ μ΄μš©ν•΄ ν˜ΈμΆœμžμ—κ²Œ μ—λŸ¬λ₯Ό λ¦¬ν„΄ν•˜λŠ” read_username_from_file ν•¨μˆ˜
  • ν•΄λ‹Ή ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ Result<String, io::Error>
    • Result<T, E> νƒ€μž…
    • μ œλ„€λ¦­ λ§€κ°œλ³€μˆ˜ T : String
    • μ œλ„€λ¦­ λ§€κ°œλ³€μˆ˜ E : io:Error
  • λŸ¬μŠ€νŠΈλŠ” μ—λŸ¬ μ „νŒŒν•˜κΈ° μž‘μ—…μ„ 더 μ‰½κ²Œ μ²˜λ¦¬ν•  수 μžˆλ„λ‘ ? μ—°μ‚°μž 제곡

(1) ? μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄ μ—λŸ¬λ₯Ό 더 μ‰½κ²Œ μ „νŒŒν•˜κΈ°

use std::io::{self, Read};
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

fn main() {
    println!("{:?}", read_username_from_file());
}
  • Result κ°’ 뒀에 뢙인 ? μ—°μ‚°μžλŠ” match ν‘œν˜„μ‹μ„ μ΄μš©ν•œ μ²˜λ¦¬μ™€ 거의 같은 λ°©μ‹μœΌλ‘œ λ™μž‘ν•¨
  • Result 값이 Ok
    • Ok 열것값에 μ €μž₯된 κ°’ 리턴 ν›„ 계속 μ‹€ν–‰
  • Result 값이 Err
    • Err 열것값이 return keywordλ₯Ό μ‚¬μš©ν•œ κ²ƒμ²˜λŸΌ 전체 ν•¨μˆ˜μ˜ 리턴값이 됨
  • match ν‘œν˜„μ‹κ³Ό ? μ—°μ‚°μž λ™μž‘μ˜ 차이점
    • ? μ—°μ‚°μžμ˜ μ—λŸ¬κ°’μ€ from ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ 전달됨
      • from ν•¨μˆ˜
        • ν‘œμ€€ λΌμ΄λΈŒλŸ¬λ¦¬μ— μ •μ˜λœ From νŠΈλ ˆμ΄νŠΈμ— μ„ μ–Έλ˜μ–΄ 있음
        • μ—λŸ¬λ₯Ό μ–΄λ–€ ν•œ νƒ€μž…μ—μ„œ λ‹€λ₯Έ νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•¨
    • ? μ—°μ‚°μžκ°€ from ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ μ „λ‹¬λœ μ—λŸ¬ νƒ€μž…μ€ ν˜„μž¬ ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ— μ •μ˜λœ μ—λŸ¬ νƒ€μž…μœΌλ‘œ λ³€ν™˜λ¨
use std::io::{self, Read};
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}

fn main() {
    println!("{:?}", read_username_from_file());
}
  • ? μ—°μ‚°μž 뒀에 λ©”μ„œλ“œλ₯Ό μ—°κ²°ν•˜μ—¬ ν˜ΈμΆœν•˜λ©΄ μ½”λ“œλ₯Ό 더 κ°„κ²°ν•˜κ²Œ μž‘μ„±μ΄ κ°€λŠ₯함
use std::{io, fs};

fn read_username_from_file() -> Result<String, io::Error> {
    fs::read_to_string("hello.txt")
}

fn main() {
    println!("{:?}", read_username_from_file());
}
  • νŒŒμΌμ„ λ¬Έμžμ—΄λ‘œ μ½λŠ” μž‘μ—…μ€ 맀우 λΉˆλ²ˆν•œ μž‘μ—…
  • λ•Œλ¬Έμ— λŸ¬μŠ€νŠΈλŠ” fs::read_to_string ν•¨μˆ˜λ₯Ό μ œκ³΅ν•¨
  • κ°„κ²°ν•˜μ§€λ§Œ μ•žμ„œ μž‘μ„±ν•œ μ½”λ“œμ™€ 같은 λ™μž‘μ„ μˆ˜ν–‰ν•¨

 

(2) ? μ—°μ‚°μžλŠ” Result νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€

  • ? μ—°μ‚°μžλŠ” match ν‘œν˜„μ‹κ³Ό 같은 λ™μž‘μ„ μ‹€ν–‰ν•˜λ„λ‘ μ •μ˜λ˜μ–΄ 있기 λ•Œλ¬Έ
    • ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ λ°˜λ“œμ‹œ Result νƒ€μž…μ΄μ–΄μ•Ό 함
  • Result νƒ€μž…μ„ λ¦¬ν„΄ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ μ•ˆμ—μ„œ Result νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•ŒλŠ” ν˜ΈμΆœμžμ—κ²Œ μ—λŸ¬λ₯Ό μ „νŒŒν•  κ°€λŠ₯성이 μžˆλŠ” ? μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜κΈ°λ³΄λ‹€ match ν‘œν˜„μ‹μ΄λ‚˜ Result νƒ€μž…μ˜ λ©”μ„œλ“œ 쀑 ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•΄μ„œ μ²˜λ¦¬ν•΄μ•Ό 함
use std::{fs::File, error::Error};

fn main() -> Result<(), Box<dyn Error>>{
    let f = File::open("hello.txt")?;

    Ok(())
}
  • main ν•¨μˆ˜λŠ” 리턴할 수 μžˆλŠ” κ°’μ˜ νƒ€μž…μ— μ œν•œμ΄ 있음
    • κ·Έ 쀑 ν•˜λ‚˜λŠ” () 이며, Result<T, E> νƒ€μž…μ„ 리턴할 μˆ˜λ„ 있음
  • Box<dyn Error> νƒ€μž…μ€ 트레이트 객체(trait object) νƒ€μž…
    • 'λͺ¨λ“  μ’…λ₯˜μ˜ μ—λŸ¬' 의미

 

3️⃣ νŒ¨λ‹‰μ— 빠질 것인가? 말 것인가?

  • Result 값을 λ¦¬ν„΄ν•˜λ©΄ 직접 결정을 λ‚΄λ¦¬λŠ” 것이 μ•„λ‹ˆλΌ ν˜ΈμΆœμžμ—κ²Œ 선택지λ₯Ό 쀄 수 있음
    • μ μ ˆν•œ 상황인 경우 μ—λŸ¬λ‘œλΆ€ν„° νšŒλ³΅μ„ μ‹œλ„
    • ν•΄λ‹Ή μ—λŸ¬λ‘œλΆ€ν„° νšŒλ³΅ν•  수 μ—†λ‹€λŠ” 결둠을 내릴 경우 νŒ¨λ‹‰ κ²°μ •
  • Result νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” 것보닀 κ·Έλƒ₯ νŒ¨λ‹‰μ„ λ°œμƒμ‹œν‚€λŠ” 것이 더 μ μ ˆν•  λ•Œλ„ 있음

πŸ€” 예제, ν”„λ‘œν† νƒ€μž… μ½”λ“œ, 그리고 ν…ŒμŠ€νŠΈ

  • unwrap κ³Ό expect λ©”μ„œλ“œλŠ” μ—λŸ¬λ₯Ό μ–΄λ–»κ²Œ μ²˜λ¦¬ν•  것인지 κ²°μ •ν•˜κΈ°μ— μ•žμ„œ ν”„λ‘œν† νƒ€μ΄ν•‘μ„ ν•΄λ³΄λŠ” 상황에 맀우 μœ μš©ν•¨
  • ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” 쀑에 λ©”μ„œλ“œ 호좜이 μ‹€νŒ¨ν•˜λ©΄ 전체 ν…ŒμŠ€νŠΈλ₯Ό μ‹€νŒ¨μ²˜λ¦¬ ν•΄μ•Ό ν•  κ²ƒμž„
    • panic! λ§€ν¬λ‘œλŠ” ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν–ˆμŒμ„ ν‘œμ‹œν•  λ•Œλ„ μ‚¬μš©ν•˜λ―€λ‘œ unwrap μ΄λ‚˜ expect λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄λ„ λ§ˆμ°¬κ°€μ§€μž„

πŸ€” μ»΄νŒŒμΌλŸ¬λ³΄λ‹€ κ°œλ°œμžκ°€ 더 λ§Žμ€ 정보λ₯Ό 가진 경우

  • Result νƒ€μž…μ˜ κ²°κ³Όκ°€ Ok κ°’μž„μ΄ ν™•μ‹€ν•˜λ”λΌλ„, μ»΄νŒŒμΌλŸ¬κ°€ 이해할 수 μ—†λŠ” 둜직이라면 unwrap λ©”μ„œλ“œλ₯Ό ν•¨κ»˜ ν˜ΈμΆœν•΄μ£ΌλŠ” 것이 μ’‹μŒ
  • ν˜ΈμΆœν•˜λŠ” μž‘μ—…μ΄ νŠΉμ • μƒν™©μ—μ„œλŠ” μ‹€νŒ¨ν•  리가 없더라도 ν†΅μƒμ μœΌλ‘œ κ·Έ μž‘μ—…μ€ μ–Όλ§ˆλ“ μ§€ μ‹€νŒ¨ν•  κ°€λŠ₯성이 있기 λ•Œλ¬Έ

πŸ€” μ—λŸ¬ 처리λ₯Ό μœ„ν•œ μ‘°μ–Έ

  • μ½”λ“œκ°€ 결ꡭ은 잘λͺ»λœ μƒνƒœκ°€ 될 상황이라면 νŒ¨λ‹‰μ„ λ°œμƒμ‹œν‚€λŠ” 것도 λ‚˜μœ 선택이 μ•„λ‹˜
    • 잘λͺ»λœ μƒνƒœ
      • μ–΄λ–€ κ°€μ„€μ΄λ‚˜ 보μž₯, 계약 ν˜Ήμ€ λΆˆλ³€μ΄μ–΄μ•Ό ν•  것듀이 깨진 상황
      • μœ νš¨ν•˜μ§€ μ•Šμ€ κ°’, λͺ¨μˆœλœ κ°’, ν˜Ήμ€ μ‹€μˆ˜λ‘œ λ†“μΉœ 값이 μ½”λ“œλ‘œ μ „λ‹¬λ˜λŠ” 상황
      • 잘λͺ»λœ μƒνƒœλŠ” μ›λž˜ κΈ°λŒ€ν–ˆλ˜ λ™μž‘μ΄ μ–΄μ©Œλ‹€ μ‹€νŒ¨ν•˜λŠ” 상황을 λ§ν•˜λŠ” 것이 μ•„λ‹˜
      • μ–΄λŠ 지점 μ΄ν›„μ˜ μ½”λ“œλŠ” ν”„λ‘œκ·Έλž¨μ΄ μ ˆλŒ€ 잘λͺ»λœ μƒνƒœμ— 놓이지 μ•Šμ•„μ•Όλ§Œ μ •μƒμ μœΌλ‘œ λ™μž‘ν•¨
      • 이 정보λ₯Ό μ‚¬μš© 쀑인 νƒ€μž…μœΌλ‘œ ν‘œν˜„ν•  방법이 μ—†μŒ
  • μ–΄λ–€ 이유둜 μž‘μ—…μ΄ μ‹€νŒ¨ν•  수 μžˆλ‹€λ©΄ panic! 맀크둜λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒλ³΄λ‹€λŠ” Result νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” 편이 λ‚˜μŒ
  • μ½”λ“œκ°€ μ–΄λ–€ 값에 λŒ€ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•  λ•ŒλŠ” κ·Έ 값이 μœ νš¨ν•œμ§€λ₯Ό λ°˜λ“œμ‹œ λ¨Όμ € κ²€μ‚¬ν•œ ν›„ 그렇지 μ•ŠμœΌλ©΄ νŒ¨λ‹‰μ„ λ°œμƒμ‹œμΌœμ•Ό 함
    • κ°€μž₯ 큰 μ΄μœ λŠ” μ•ˆμ „μ„±
  • λͺ¨λ“  ν•¨μˆ˜μ—μ„œ κ°€λŠ₯ν•œ μ—λŸ¬λ₯Ό λͺ¨λ‘ κ²€μ‚¬ν•˜λŠ” 것도 νž˜λ“  μž‘μ—…μž„
    • 러슀트의 νƒ€μž… μ‹œμŠ€ν…œ(그리고 컴파일러의 νƒ€μž… 검사)을 μ΄μš©ν•΄ μ—¬λŸ¬ 가지 검사 μˆ˜ν–‰ κ°€λŠ₯
      • ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž… 같은 κ²½μš°λŠ” μ»΄νŒŒμΌλŸ¬κ°€ ν•΄λ‹Ή νƒ€μž…μ˜ μœ νš¨ν•œ 값이 μ „λ‹¬λ˜λŠ” 것이 보μž₯λœλ‹€λŠ” 것을 μ•Œκ³  μžˆμœΌλ―€λ‘œ μΆ”κ°€ 검사 없이 λ‘œμ§μ„ κ΅¬ν˜„ν•΄ λ‚˜κ°€λ©΄ 됨

πŸ€” μœ νš¨μ„± 검사λ₯Ό μœ„ν•œ μ»€μŠ€ν…€ νƒ€μž…

  • μƒˆλ‘œμš΄ νƒ€μž…μ„ μƒμ„±ν•˜κ³  이 νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” ν•¨μˆ˜μ— μœ νš¨μ„± 검사 μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 것이 맀우 효율적인 방법

 

Summary

  • panic! 맀크둜
    • ν”„λ‘œκ·Έλž¨μ΄ μ œλŒ€λ‘œ μ²˜λ¦¬ν•  수 μ—†λŠ” 비정상적인 μƒνƒœμ— λ†“μ˜€λ‹€λŠ” 것을 μ•Œλ €μ£Όκ³  μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜ 잘λͺ»λœ 값을 계속 μ‚¬μš©ν•˜μ§€ λͺ»ν•˜λ„둝 ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œν•¨
  • Result μ—΄κ±°μž
    • 러슀트의 νƒ€μž… μ‹œμŠ€ν…œμ„ μ΄μš©ν•΄ μž‘μ—…μ΄ μ‹€νŒ¨ν•  μˆ˜λ„ μžˆμŒμ„ λͺ…μ‹œν•˜κ³ , μ‹€νŒ¨ν•œ 경우 ν”„λ‘œκ·Έλž¨μ„ νšŒλ³΅ν•  기회λ₯Ό μ œκ³΅ν•¨
    • Result νƒ€μž…μ„ λ¦¬ν„΄ν•΄μ„œ 호좜 μ½”λ“œκ°€ μž‘μ—…μ΄ μ„±κ³΅ν•œ κ²½μš°μ™€ μ‹€νŒ¨ν•œ 경우λ₯Ό λͺ¨λ‘ μ²˜λ¦¬ν•  수 μžˆλ„λ‘ μœ λ„ κ°€λŠ₯
728x90
λ°˜μ‘ν˜•
Comments