관리 메뉴

나만을 위한 블로그

[Kotlin] runCatching이란? runCatching 사용법 본문

개인 공부/Kotlin

[Kotlin] runCatching이란? runCatching 사용법

참깨빵위에참깨빵 2023. 3. 26. 02:32
728x90
반응형

자바에서 try-catch를 통해 예외가 발생할 것으로 예상되는 부분을 try 블록으로 감싸고 catch 블록에는 예외 발생 시 처리할 로직들을 넣는 전통적인 예외처리법을 사용했다. 이 방법은 코틀린에서도 사용할 수 있고 현재도 자주 쓰이지만 코틀린은 다른 예외처리 방법을 제공하는데 제목에 써 둔 runCatching이란 것이다.

코틀린 공식문서에서 설명하는 runCatching은 아래와 같다.

 

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run-catching.html

 

runCatching - Kotlin Programming Language

 

kotlinlang.org

지정된 함수 블록을 호출하고 호출이 성공하면 캡슐화된 결과를 반환하고 블록 함수 실행에서 발생한 Throwable 예외를 포착해 실패로 캡슐화한다

 

인텔리제이에서 확인한 runCatching의 구현은 아래와 같다.

 

@InlineOnly
@SinceKotlin("1.3")
public inline fun <R> runCatching(block: () -> R): Result<R> {
    return try {
        Result.success(block())
    } catch (e: Throwable) {
        Result.failure(e)
    }
}

 

inline 키워드가 붙어 있고 내부적으로 try-catch를 쓰고 있는 게 눈에 띈다. 리턴 타입은 매개변수로 받은 함수 타입이 반환하는 값과 같은 값을 갖는 Result 타입이다. 성공 시 Result.success() 안에서 함수 타입 매개변수를 실행해 리턴하고 실패 시 Result.failure()로 Throwable을 넘긴다.

 

아래는 runCatching을 사용하는 예제다. 숫자를 입력받았다고 가정하고 문자열로 바꿀 수 있는 경우, 없는 경우에 각각 다른 처리를 하는 코드다.

 

fun main() {
    val input = "123"
    val result = runCatching { input.toInt() }
        .onSuccess { value -> println("변환 성공 : $value") }
        .onFailure { exception -> println("변환 실패 : $exception") }
    println(result)
}

// >> 변환 성공 : 123
// >> Success(123)

 

runCatching {} 안에는 예외가 발생할 수 있는 코드를 넣는다. 그리고 뒤에 잇따르는 onSuccess, onFailure 블록에선 각각 문자열을 숫자로 변환 성공, 실패한 경우 수행할 처리들을 넣는다. 이 예제는 실행 시 당연히 성공하며 마지막에 result 변수를 출력하면 숫자로 바뀐 123이 Success()에 감싸여 있는 걸 볼 수 있다. 위에서 말한 대로 호출이 성공해서 Result 타입으로 캡슐화된 응답이 반환된 것이다.

같은 코드를 try-catch를 사용한 방식으로 바꾸면 아래와 같다.

 

fun main() {
    val input = "123"

    try {
        val value = input.toInt()
        println("변환 성공: $value")
    } catch (exception: NumberFormatException) {
        println("변환 실패: ${exception.message}")
    }
}

 

 

 

두 방식 모두 같은 결과를 내지만 try-catch의 경우 예외 처리, 결과 처리가 섞여 있어서 가독성 면에선 runCatching {}이 좀 더 좋아 보인다.

runCatching {}의 장점은 아래와 같다.

 

  • try-catch 보다 간결한 형태로 예외처리 코드를 쓸 수 있어 상대적으로 가독성이 좋다
  • onSuccess, onFailure, getOrElse 등의 함수를 연달아 쓸 수 있는 함수 체이닝이 가능하다

 

그러나 단점도 있기 마련이다.

 

  • Result 타입을 사용해 성공 / 실패를 리턴하기 때문에 try-catch보다 상대적으로 성능 저하가 일어날 수 있다

 

try-catch 대신 runCatching {}을 무조건 사용하는 것은 좋지 않아 보인다. 가독성이 좋아 보이더라도 이걸 썼을 때 정말로 더 가독성이 좋은 코드가 만들어지는지, 협업의 관점에서 어떤 걸 써야 명확하고 깔끔하게 예외처리할 수 있는지 등을 검토해서 자신의 상황에 맞는 걸 사용하자.

 

 

반응형
Comments