Kotlin 의 .takeIf()
& .takeUnless()
함수
Kotlin
v1.9.22
버전 기준 블로그 작성
.takeIf()
takeIf()
함수는 프로그래밍 역사상 오래 전부터 즐겨 사용하는 if
문과 같은 객체의 상태를 체크하는 로직에서 대체하여 활용할 수 있다.
if
문에 들어가는 조건식을 takeIf()
함수에서는 람다 파라미터로 전달되는데,
- 람다 조건식이
true
라면, 수신 객체를 반환하고, - 람다 조건식이
false
라면,null
을 반환한다.
// 일반 if 문
if (condition) {
doSomething()
}
// takeIf() 문
takeIf { condition }?.apply { doSomething() }
.takeUnless()
takeUnless()
함수는 takeIf()
함수의 반대 동작하는 함수이다.
- 람다 조건식이
true
라면,null
을 반환하고, - 람다 조건식이
false
라면, 수신 객체를 반환한다.
takeIf()
함수의 내부
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#takeif-and-takeunless).
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (predicate(this)) this else null
}
해당 코드에서도 확인할 수 있듯이 if
문을 통해서 아래와 같이 동작한다.
predicate(this) == true
인 경우,this
반환predicate(this) == false
인 경우,null
반환
takeIf()
함수 활용
Kotlin
을 활용하다보면, 불변 또는 가변 제약으로 인해 if
문을 통한 객체 변환 로직에서 불가피하게 또다른 빈 객체가 필요할 때가 있다.
takeIf()
함수를 잘 사용하면 위와 같은 상황 또는 복잡한 if
문에 대한 가독성을 높일 수 있는 리팩토링이 가능할 것 같다.
기본 함수 사용법
@Test
fun `takeIf() 함수 기본 사용법`() {
val status = true
takeIf { status }?.apply { println("Hello World") }
takeIf { false }?.apply { println("Hello World") } ?: println("Hell World")
val str = "Hello !"
str.takeIf { status }?.apply { println("$this World !") }
val str2 = ""
str2.takeIf { it.isNotEmpty() }?.apply { println("$this World !!") } ?: println("Nothing !!")
}
Output
Hello World
Hell World
Hello ! World !
Nothing !!
확장 함수 활용한 사용법
@Test
fun `String 확장 함수 이용한 takeIf() 함수 사용법`() {
stringTakeIfWithWorld("Hello")?.apply { println(this) }
stringTakeIfWithWorld(null)?.apply { println(this) } ?: println("Nothing !!")
}
private fun stringTakeIfWithWorld(str: String?): String? {
return str?.takeIf { "Hello" == str }?.add("World")
}
private fun String.add(str: String): String {
return "$this $str"
}
Output
Hello World
Nothing !!
String
예시 외에도 다양한 객체를 활용할 수 있을 것이다. 몇가지 예시는 Kotin 공식 홈페이지에서도 확인 가능하다.
정리
중첩 if
문 또는 복잡한 조건으로 인한 가독성 저하되는 if
문에 대해서 항상 고민을 가지고 있었다.
takeIf()
문을 잘 활용한다면, 위와 같은 고민을 조금 더 해결할 수 있을 것 같은 느낌이다. 😁