After reading Rust book chapter 9

rust



에러의 종류

1. recoverable error

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


2. unrecoverable error


Unrecoverable Errors with panic! 매크로

// (1) panic! 매크로 직접 호출하기
fn main() {
    panic!("crash and burn");
}
// (2) panic! 발생하는 예:
// 벡터의 크기를 벗어난 인덱스로 값을 읽는 경우
fn main() {
  let v = vec![1,2,3];

  v[99];
}



Recoverable Errors with Result enum

match 표현식을 이용해 리턴된 Result 타입의 리턴값 처리

use std::fs::File;

fn main() {
  // f: Result<File, std::io::Error>
  let f = File::open("hello.txt");

  let f = match f {
      Ok(file) => file,
      Err(error) => {
          panic!("파일 열기 실패: {:?}", error);
      }
  };
}


match 표현식으로 여러 종류의 에러 처리하기

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

fn main() {
  // f: Result<File, std::io::Error>
  let f = File::open("hello.txt");

  /**
    * 파일 열기 시도 실패 시
    * => error.kind가 NotFound 인지 확인
    * => 파일 생성 => 파일 생성 성공 / 실패 따른 처리
    */
  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!("파일을 생성하지 못했습니다: {:?}", e),
          },
          other_error => panic!("파일을 열지 못했습니다: {:?}", other_error),
      },
  };
}


Result::unwrap()

use std::fs::File;

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


Result::expect()

use std::fs::File;

fn main() {
  let f = File::open("hello.txt").expect("파일을 열 수 없습니다.");
}



에러 전파하기

1. return Err(e)

use std::fs::File;
use std::io;
use std::io::Read;

fn main() {
  fn read_username_from_file() -> Result<String, io::Error> {
      let f = File::open("hello.txt");
      let mut f = match f {
          Ok(file) => file,
          Err(e) => return Err(e), // 함수 실행 조기 중단, 에러값을 호출자에 리턴
      };
      let mut s = String::new();
      // read_to_string: 파일의 내용을 변수에 기록, Result 타입 리턴
    match f.read_to_string(&mut s) {
          Ok(_) => Ok(s),
          Err(e) => Err(e), // 함수의 마지막 표현식이므로 return 키워드 명시 X
      }
  }
}


2. ? 연산자

fn read_username_from_file() -> Result<String, io::Error> {
		// ok, err값을 다르게 처리하면서 에러발생시 에러를 반환하고 종료
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
}



언제 panic! 매크로를 사용하는가?