[이펙티브 코틀린] 1장 안정성 Item 7 결과 부족이 발생할 경우 null과 Failure를 사용하라

Sdoubleu·2023년 1월 6일
0

이펙코

목록 보기
7/7
post-thumbnail

함수가 원하는 결과를 만들어 낼 수 없을 때, 이러한 상황을 처리하는 매커니즘

  1. null 또는 '실패를 나타내는 sealed 클래스(일반적으로 Failure라는 이름을 붙임)'를 리턴
  2. 예외를 throw

이러한 두 가지는 ⚡중요한 차이점 존재

  1. 예외는 정보를 전달하는 방법으로 사용해서는 안됨
  2. 예외는 잘못된 특별한 상황을 나타내야 하며, 처리돼야 함
  3. 예외를 예외적인 상황이 발생했을 때 사용하는 것이 좋음

-> 많은 개발자가 예외가 전파되는 과정을 제대로 추적 못함
-> 코틀린의 모든 예외는 unchecked 예외임. 따라서 예외를 처리하지 않을 수도 있음

  • 사용자가 반드시 처리하게 강제되는 예외를 checked 예외라고 부르고,
  • 처리하지 않아도 실행에 문제가 없는 예외를 unchecked 예외라고 부름
  • 예외는 예외적인 상황을 처리하기 위해서 만들어졌으므로 명시적인 테스트만큼 빠르게 동작❌
  • try-catch 블록 내부에 코드를 배치하면, 컴파일러가 할 수 있는 최적화가 제한

  • nullFailure 는 예상되는 오류를 표현할 때 좋음👍
    -> 명시적이고, 효율적이며, 간단한 방법으로 처리 가능

예측 가능 범위의 오류 -> nullFailure
예측 불가능 범위의 오류 -> throw

ex)

inline fun <reified T> String.readObjectOrNull(): T? {
	//...
    if(incorrectSign) {
    	return null
	}
    //...
    return result
}

inline fun <reified T> String.readObject(): Result<T> {
	//...
    if(incorrectSign) {
    	return Failure(JsonParsingException())
    }
    //...
    return Success(result)
}

sealed class Result<out T>
class Success<out T>(val result: T): Result<T>()
class Failure<val throwable: Throwable): Result<Nothing>()

class JsonParsingException: Exception()

↪ 이렇게 표시되는 오류는 다루시 쉬우며 놓치기 어려움

null을 처리해야 한다면, 안전 호출(safe call) or Elvis 연산자 같은 다양한
널 안정성 기능을 활용 !

  • Result와 같은 공용체를 리턴하기로 했다면, when 표현식 사용
val person = userText.readObjectOrNull<Person>()
val age = when(person) {
	is Success -> person.age
    is Failure -> -1
}

↪ try-catch보다 효율적, 쉽고 명확함


null 값과 sealed result 클래스의 차이

  • sealed result : 추가적인 정보를 전달해야 할 때

  • null : 일반적

  • Failure : 처리할 때 필요한 정보를 가질 수 있음

일반적으로 두 가지 형태의 함수를 사용
하나는 예상 가능, 다른 하나는 예상 불가능

  • get : 특정 위치에 있는 요소를 추출할 때 사용
    -> 해당 위치에 없다면 IndexOutOfBoundException 발생

  • getOrNull : 오류가 발생할 수 있는 경우에 사용
    -> 오류 발생 시 null return

이외에도 getOrDefault 같은 선택지 존재
하지만 getOrNull or Elvis 연산자(?:)가 더 쉬움👍



개발자는 항상 자신이 안전하게 추출할 거라고 생각
따라서 nullable 리턴 ❌ !!!
개발자에게 null이 발생할 수 있다는 경고를 주려면,
-> getOrNull 등과 같은 예측가능한 리턴 사용 !!

profile
개발자희망자

0개의 댓글