[Kotlin] takeIf 사용하기

2024. 5. 10. 20:34·Kotlin

Kotlin에서 제공하는 다양한 표준 라이브러리 함수들은 보다 간결하고 안전한 코드를 작성하는데 도움이 된다.  그 중에서 takeIf 함수는 조건에 따라 값의 반환 여부를 결정하는 함수로 가독성 증가와 유지 관리를 향상시킬 수 있다. 이 글에서는 takeIf 함수의 기본 사용법과 여러 가지 예제를 통해 이해하기 쉽게 설명해보고자 한다.

 

takeIf란?

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/take-if.html

 

takeIf - Kotlin Programming Language

 

kotlinlang.org

공식 Kotlin 사이트의 간단한 설명을 참고해보자면

Returns this value if it satisfies the given predicate or null, if it doesn't.

즉 주어진 predicate(술어)를 만족하면 그 값을 반환하고 만족하지 않다면 null을 반환하는 함수이다.  자바의 if를 대체해서 사용할 수 있어 본인의 코드 스타일에 따라 if문을 전부 대체하는 것도 가능하지만 이해를 위한 기본 지식이 필요하므로 상황에 따라 알맞게 사용하도록 한다.

 

takeIf 구조

inline fun <T> T.takeIf(predicate: (T) -> Boolean): T?

함수를 보면 제네릭 타입 T에 takeIf를 사용하면 T?를 반환하는 것으로 보아 값 또는 null을 반환할 수 있는 함수라는 것을 알 수 있다.  T는 제네릭 타입이므로 어떠한 타입의 객체에 대해서도 takeIf를 사용할 수 있고 내부에서 그 값을 사용해서 조건을 만들 수도 있으며 조건을 판단해 Boolen 객체로 반환해 true를 반환한다면 T를, false를 반환하면 null을 반환하게 된다. 

 

값에 takeIf 사용하기

제네릭 타입이므로 당연하게도 값에 사용할 수 있다. 

예를 들어 조건 A와 값 a가 있다고 하자. 

a.takeIf { A }

- 만약 조건 A가 True라면 코드는 값 a를 반환하고 조건 A가 false라면 null을 반환하게 된다. 

 

이번에는 상태 A와 상태 B, 값 a가 있다.

1) a.takeIf { it == A }

2) a.takeIf { value -> value == A}

3) a.takeIf { it == A || it == B }

- 함수 내부에서 it으로 takeIf를 사용한 값(a)을 호출할 수 있으며 it shadow 경고를 피하기 위해 (2)처럼 직접 이름을 설정해 사용할 수도 있다.

- (1)은 값 a가 상태 A라면 값 a를 반환하고 동일하지 않다면 null을 반환하며 (3)은 값 a가 상태 A 또는 상태 B라면 값 a를 반환, 두 상태 모두 아니라면 null을 반환한다. 

 

이 때 주의할 점은 null 가능성이 있는 필드에서는 문제없이 사용할 수 있지만 null을 허용하지 않는 필드에서 사용하려면 null일 때의 값을 지정해주어야 null 가능성을 가지지 않는다. 

a.takeIf { A }?: b

- ?: 를 사용해서 null일 때의 값을 지정해주면 조건 A가 만족한다면 값 a를, 만족하지 않는다면 값 b를 사용하여 null을 반환할 가능성이 사라지며 문제가 해결되게 된다.

 

단순히 값을 반환하는 것뿐만 아니라 조건에 따라 작업을 실행할 수도 있다.

1) a.takeIf { A }?.let { a.value = b } ?: run { a.value = c }

2) a.takeIf { A }?.let { b.value = it } ?: run { b.value = a }

- (1)은 조건 A가 만족한다면 let문을 실행해 값 a를 값 b로 설정하고 만족하지 않는다면 run문을 실행해 값 a를 값 c로 설정한다. 

- (2)는 조건 A가 만족한다면 값 b를 it(값 a)로 설정하며 만족하지 않는다면 값 b를 a로 설정한다. 이 때 run문에서는 takeIf를 통해 생성된 it을 참고할 수 없으므로 직접 값 a를 사용해야 한다. 

 

조건에 takeIf 사용하기

앞서 설명한 값에 takeIf를 사용하는 방법 외에 조건문 자체에도 takeIf를 사용할 수 있다. 

1) A.takeIf { it }

2) A.takeIf { contidion -> condition }

- 조건 A에 takeIf를 사용하고 { } 내부에서 해당 조건인 it을 호출하면 해당 코드는 조건 A 또는 null을 반환하며 마찬가지로 이름을 직접 설정해서 사용할 수도 있다. 

 

조건에 takeIf를 사용해서 조건을 반환한다면 굳이 사용해야할 이유가 없다. 따라서 null 처리를 해주면서 값 또는 작업을 반환해주는 식으로 사용하는 것이 좋다. 

1) A.takeIf { it }?.let { a } ?: b 

2) A.takeIf { it }?.let { Job a } ?: run { Job b }

- (1)은 조건 A가 만족한다면 값 a를 반환하고 만족하지 않는다면 b를 반환한다. 

 

- (2)는 조건 A가 만족한다면 작업 a를 실행하고 만족하지 않는다면 작업 b를 반환한다. 

 

두 가지 방법의 차이점

그렇다면 값에 takeIf를 사용하는 방법과 조건에 takeIf를 사용하는 방법의 차이점은 무엇이 있을까. 사실 큰 차이는 없다. 그렇지만 특정 상황에서는 큰 차이가 있을 수 있다.

1) isLinkValid.value.takeIf { it }?.let { URL(linkURL.value) }

2) URL(linkURL.value).takeIf { isLinkValid.value }

- 먼저 가장 중요한 takeIf의 작동 방식은 if문과는 달리 takeIf 앞의 값이 항상 먼저 실행된다는 것이다.

 

- linKURL의 값이 유효한 URL형식인지를 판단하는 isLinkValid와 linkURL을 URL형식으로 만들어주는 함수 URL이 있다. 이 때  isLinkValid의 값은 linkURL이 변할 때마다 자동으로 계산된다고 하자.

 

- (1)은 isLinkValid의 Boolen을 판단하고 만족한다면 let문을 실행해서 URL(linkURL.value)를 반환하고 만족하지 않는다면 null을 반환한다. (2)은 URL(linkURL.value)를 isLinkValid라는 조건이 만족한다면 반환하고 만족하지 않는다면 null을 반환한다.

 

여기서 URL 함수는 허용하지 않는 URL형식을 입력받는다면 에러가 생기게 된다. 만약 에러가 생긴다면 1번과 2번 중 어느 곳에서 생기게 될까?

 

- 에러는 (2)에서 발생할 수 있다. URL(linkURL.value)를 실행한 후 takeIf를 실행하기 때문이다. 1번은 만약 linkURL이 유효한 형식이 아니라면 isLinkValid가 만족하지 않으므로 let문에 도달할 수 없어 오류가 발생하지 않지만 2번은 linkURL가 유효한 형식이 아니라면 즉시 에러가 발생하게 된다. 

'Kotlin' 카테고리의 다른 글
  • [Kotlin] LocalDateTime Format하기
  • [Kotlin] Long to LocalDateTime, LocalDateTime to Long 변환하기
브애애앳
브애애앳
  • 브애애앳
    디벨로퍼즐
    브애애앳
  • 전체
    오늘
    어제
    • 분류 전체보기 (24) N
      • Jetpack Compose (15)
      • Kotlin (3)
      • Android Studio (2)
      • Tistory (1)
      • Android App (3) N
  • 인기 글

  • hELLO· Designed By정상우.v4.10.0
브애애앳
[Kotlin] takeIf 사용하기
상단으로

티스토리툴바