다음은 사용하려는 스타일, 모든 유형이 같거나 다른 경우, 목록에 알 수없는 항목 수에 따라 몇 가지 변형이 있습니다.
혼합 유형, 새 값을 계산하려면 모두 null이 아니어야합니다.
혼합 유형의 경우 어리석게 보일 수 있지만 혼합 유형에 대해 잘 작동하는 각 매개 변수 수에 대해 일련의 함수를 빌드 할 수 있습니다.
inline fun <T1: Any, T2: Any, R: Any> safeLet(p1: T1?, p2: T2?, block: (T1, T2)->R?): R? {
return if (p1 != null && p2 != null) block(p1, p2) else null
}
inline fun <T1: Any, T2: Any, T3: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, block: (T1, T2, T3)->R?): R? {
return if (p1 != null && p2 != null && p3 != null) block(p1, p2, p3) else null
}
inline fun <T1: Any, T2: Any, T3: Any, T4: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, block: (T1, T2, T3, T4)->R?): R? {
return if (p1 != null && p2 != null && p3 != null && p4 != null) block(p1, p2, p3, p4) else null
}
inline fun <T1: Any, T2: Any, T3: Any, T4: Any, T5: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, p5: T5?, block: (T1, T2, T3, T4, T5)->R?): R? {
return if (p1 != null && p2 != null && p3 != null && p4 != null && p5 != null) block(p1, p2, p3, p4, p5) else null
}
// ...keep going up to the parameter count you care about
사용 예 :
val risk = safeLet(person.name, person.age) { name, age ->
// do something
}
목록에 null 항목이 없을 때 코드 블록 실행
여기서 두 가지 특징은 목록에 null이 아닌 항목이 모두있을 때 코드 블록을 실행하는 것이고, 두 번째는 목록에 null이 아닌 항목이 하나 이상있을 때 동일한 작업을 수행하는 것입니다. 두 경우 모두 null이 아닌 항목 목록을 코드 블록에 전달합니다.
기능 :
fun <T: Any, R: Any> Collection<T?>.whenAllNotNull(block: (List<T>)->R) {
if (this.all { it != null }) {
block(this.filterNotNull()) // or do unsafe cast to non null collectino
}
}
fun <T: Any, R: Any> Collection<T?>.whenAnyNotNull(block: (List<T>)->R) {
if (this.any { it != null }) {
block(this.filterNotNull())
}
}
사용 예 :
listOf("something", "else", "matters").whenAllNotNull {
println(it.joinToString(" "))
} // output "something else matters"
listOf("something", null, "matters").whenAllNotNull {
println(it.joinToString(" "))
} // no output
listOf("something", null, "matters").whenAnyNotNull {
println(it.joinToString(" "))
} // output "something matters"
함수가 항목 목록을 받고 동일한 작업을 수행하도록 약간 변경했습니다.
fun <T: Any, R: Any> whenAllNotNull(vararg options: T?, block: (List<T>)->R) {
if (options.all { it != null }) {
block(options.filterNotNull()) // or do unsafe cast to non null collection
}
}
fun <T: Any, R: Any> whenAnyNotNull(vararg options: T?, block: (List<T>)->R) {
if (options.any { it != null }) {
block(options.filterNotNull())
}
}
사용 예 :
whenAllNotNull("something", "else", "matters") {
println(it.joinToString(" "))
} // output "something else matters"
이러한 변형은 다음과 같은 반환 값을 갖도록 변경할 수 있습니다. let()
.
null이 아닌 첫 번째 항목 사용 (Coalesce)
SQL Coalesce 함수와 유사하게 null이 아닌 첫 번째 항목을 반환합니다. 기능의 두 가지 특징 :
fun <T: Any> coalesce(vararg options: T?): T? = options.firstOrNull { it != null }
fun <T: Any> Collection<T?>.coalesce(): T? = this.firstOrNull { it != null }
사용 예 :
coalesce(null, "something", null, "matters")?.let {
it.length
} // result is 9, length of "something"
listOf(null, "something", null, "matters").coalesce()?.let {
it.length
} // result is 9, length of "something"
기타 변형
... 다른 변형이 있지만 사양이 더 많으면 범위를 좁힐 수 있습니다.