에러 처리

러스트는 에러도 일반적인 값으로 다룬다.

기존 언어와의 차이점

1. 예외가 없다

자바나 파이썬은 에러가 나면 throw를 하고, 누군가 catch 할 때까지 스택을 되감는다. (제어 흐름이 확 바뀜)

러스트 에러는 그냥 return 값일 뿐 제어흐름의 점프는 없다. 에러를 처리하는 흐름이 코드에 명시적으로 보인다.

2. 처리 안 하면 컴파일이 안 된다

다른 언어는 에러 처리를 까먹어도 일단 실행은 된다.

러스트에선 Result를 리턴했는데 ?unwrapmatch 등으로 처리하지 않으면 타입 불일치로 컴파일 자체가 안 된다.

Result

Ok(T) 혹은 Err(E) 값을 갖는 이늄 타입이다.

이늄이기 때문에 에러인지 아닌지 매칭하지 않으면 값을 꺼낼 수 없다.

Result.ok()

Result에서 에러정보를 버리고 Option로 변환한다.

Option.ok_or(error_value)

Option를 Result로 변환한다. None인 경우 Err(error_value)가 된다.

unwrap()

보통은 매칭을해야하지만 절대 에러가 날 수 없는경우이거나 즉시 프로그램이 중단되는것이 나은경우 사용한다. 만약 값이 Err면 프로그램은 종료된다.

unwrap_or(`표현식`)

결과값이 Err인 경우 `표현식`을 평가한 값으로 평가된다.

unwrap_or_else(`FnOnce를 구현한 객체`)

결과값이 Err인경우 인자로 들어온 함수의 값으로 평가된다. 대체값을 지연평가하고 싶을때 사용한다.

unwrap_or_default()

결과값이 Err인 경우 해당 타입의 기본값을 반환한다. 해당 타입 Default 트레이트를 구현해야 한다.

expect("메시지")

unwrap과 동일하지만 종료하면서 메시지를 던진다.

? (물음표 연산자)

값이 Err인경우 에러를 호출측에서 처리하도록 즉시 에러값과 함께 리턴한다.

match res {
    Ok(val) => { do_something(val); },
    Err(e) => { return e; }
}

// 위와 아래는 동일하다


do_something(res?);

코드가 간결해지고 읽기 흐름을 막지 않는다.

panic! 매크로

코드가  패닉을 일으킬만한 동작을 하거나 panic! 매크로를 명시적으로 작성하면 프로그램에 패닉이 발생.

프로그램을 계속 동작시키키보다 즉시 종료하는편이 나은 경우에 사용한다.

일반적으로  패닉이 일어나면 실패 메시지를 출력하고, 스택을 훑으며 데이터를 청소하는 unwinding 을 하고 프로그램을 종료한다. 하지만 panic = 'abort' 로 데이터 정리 대신 즉시 그만두는 방식을 차용할 수도 있다.