Kotlin/Kotlin
Kotlin takeIf와 takeUnless 함수
Junuuu
2024. 3. 13. 00:01
728x90
개요
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