-
Kotlin takeIf와 takeUnless 함수Kotlin/Kotlin 2024. 3. 13. 00:01
개요
Kotlin에서 takeIf()와 takeUnless() 함수를 제공한다는 사실을 알게 되었고, 해당 함수들에 대해서 알아보고자 합니다.
takeIf 함수
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? { contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) } return if (predicate(this)) this else null }
takeIf 함수는 T (어떤 객체)의 확장함수입니다.
predicate를 인자로 받아서 조건에 만족하는경우 자기 자신을 반환하거나 null을 반환합니다.
takeUnless 함수
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? { contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) } return if (!predicate(this)) this else null }
takeIf 함수와 굉장히 유사하지만 return 구문의 ! 부정문이 들어가 있어서 takeIf와 반대로 동작합니다.
직접 호출해보며 takeIf, takeUnless 함수 이해해 보기
@Test fun `takeIf, takeUnless 메서드 사용하기`(){ val simpleNumber = 3 println(simpleNumber.takeIf { true }) // 3 println(simpleNumber.takeUnless { true }) // null }
결과는 3과 null이 나오게 됩니다.
즉, Predicate 구문에 따라 T 객체를 반환할 건지 null을 반환할건지 결정됩니다.
언제 사용하면 좋을까?
// 원본 코드 if (status) { doThis() } // 수정 된 코드 takeIf { status }?.apply { doThis() }
무작정 takeIf를 활용한다고 하면 오히려 가독성이 떨어질 수 있습니다.
takeIf, takeUnless 함수가 Predicate에 따라 null을 반환하기 때문에 null을 다루는 코드에 사용하면 좋을 것 같습니다.
예시) null을 다루는 코드에 takeIf, takeUnless 적용하기
@Test fun `takeIf, takeUnless 적합한 상황은 언제일까`(){ val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val evenNumbers = numbers.filter { it % 2 == 0 } val oddNumbers = numbers.filterNot { it % 2 == 0 } val evenNumbers2 = numbers.mapNotNull { it.takeIf { number -> number % 2 == 0 } } val oddNumbers2 = numbers.mapNotNull { it.takeUnless { number -> number % 2 == 0 } } }
홀수와 짝수를 구분하는 상황에서 filter를 활용하는 것도 좋은 예시입니다.
하지만 mapNotNull을 활용하는 경우라면 takeIf, takeUnless도 활용해 볼 수 있습니다.
참고자료
https://kotlinlang.org/docs/scope-functions.html#takeif-and-takeunless
'Kotlin > Kotlin' 카테고리의 다른 글
kotlin enum 상태 관리 구현하기 (3) 2024.09.27 Kotlin fold, reduce 메서드 (0) 2024.03.10 Kotlin associateBy, groupBy 함수 (0) 2024.03.09 kotlin interface default method (0) 2024.03.05 kotlin delegated properties (0) 2024.03.01