코틀린 스터디/이펙티브 코틀린

아이템7) 결과 부족이 발생한 경우 null과 Failure를 사용하라

막이86 2024. 2. 22. 13:34
728x90

이펙티브 코루틴을 요약한 내용입니다

  • 함수가 원하는 결과를 만들어 낼 수 없을 때
    • 서버로부터 데이터를 읽어 들이려고 했는데, 인터넷 연결 문제로 읽어 들이지 못한 경우
    • 조건에 맞는 첫 번째 요소를 찾으려 했는데, 조건에 맞는 요소가 없는 경우
    • 텍스트를 파싱해서 객체를 만들려고 했는데, 텍스트의 형식이 맞지 않은 경우
  • 원하는 결과를 만들어 낼 수 없을 때 처리 메커니즘
    • null 또는 ‘실패를 나타내는 sealed 클래스(Failure 이름을 붙임)`를 리턴
    • 예외를 throw
  • 예외는 정보를 전달하는 방법으로 사용해서는 안됨
    • 예외는 잘못된 특별한 상황을 나타내야 함
    • 예외는 예외적인 상황이 발생했을 때 사용하는 것이 좋음
  • 예외는 예외적인 상황이 발생되었을 때 사용 - 이팩티브 자바의 내용
    • 예외가 전파되는 과정을 제대로 추적하지 못함
    • 사용자가 예외를 처리하지 않을 수 있음
      • API를 사용할 때 예외와 관련된 사항을 단순하게 메서드를 사용하면 파악하기 힘듬
    • 예외는 예외적인 상황을 처리하기 위해 만들어졌음
      • 명시적인 테스트 만큼 빠르게 동작하지 않음
    • try-catch 블록 내부에 코드를 배치하면, 컴파일러가 할수 있는 최적화가 제한 됨
  • null 또는 Failure는 예상되는 오류를 표현할때 좋음
    • 명시적, 효율적, 간단한 방법
  • 예측하기 어려운 예외적인 범위의 오류는 예외를 throws 해서 처리
inline fun <reified T> String.readObjectOrNull(): T? {
	if (incorrectSign) {
		return null
	}

	return result
}

inline fun <reified T> String.readObject(): Result<T> {
	if (incorrectSing) {
		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()
  • 명시적인 오류는 다루기 쉬우며 놓치기 어려움
  • Result와 같은 공용체(union type)를 리턴하기로 했다면, when 표현식을 사용해서 이를 처리
    • try-catch 블록보다 효율적
    val person = userText.readObjectOrNull<Person>()
    val age = when(person) {
    	is Success -> person.age
    	is Failure -> -1
    }
    
  • null 값과 sealed result 클래스의 차이점
    • 추가적인 정보 전달 → sealed result
    • 추가적인 정보 전달 X → null
  • 일반적으로 두 가지 형태의 함수 사용 (List 예제)
    • get: 특정 위치에 있는 요소를 추출할 때 사용
      • 해당 위치에 없다면 IndexOutOfBoundsException 발생
    • getOrNull: out of range 오류가 발생할 수 있는 경우에 사용
      • 해당 위치에 없다면 null을 리턴
  • getOrNull 또는 Elvis 연산자를 사용하는거시 쉬움
728x90