İşte hangi stili kullanmak istediğinize bağlı olarak, aynı veya farklı türde her şeye sahipseniz ve liste bilinmeyen sayıda öğe varsa ...
Karışık türler, yeni bir değer hesaplamak için tümü boş olmamalıdır
Karma türler için, her parametre sayısı için aptalca görünebilecek, ancak karma türler için iyi çalışan bir dizi işlev oluşturabilirsiniz:
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
Örnek kullanım:
val risk = safeLet(person.name, person.age) { name, age ->
// do something
}
Listede boş öğe olmadığında kod bloğunu çalıştır
Buradaki iki çeşit, ilk olarak bir liste boş olmayan tüm öğelere sahip olduğunda kod bloğunu yürütmek ve ikincisi, bir liste en az bir boş olmayan öğe içerdiğinde aynı şeyi yapmaktır. Her iki durum da kod bloğuna boş olmayan öğelerin bir listesini iletir:
Fonksiyonlar:
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())
}
}
Örnek kullanım:
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"
İşlevin öğe listesini alması ve aynı işlemleri yapması için küçük bir değişiklik:
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())
}
}
Örnek kullanım:
whenAllNotNull("something", "else", "matters") {
println(it.joinToString(" "))
} // output "something else matters"
Bu varyasyonlar, gibi dönüş değerlerine sahip olacak şekilde değiştirilebilir let()
.
İlk boş olmayan öğeyi kullanın (Coalesce)
SQL Coalesce işlevine benzer şekilde, boş olmayan ilk öğeyi döndürür. Fonksiyonun iki çeşidi:
fun <T: Any> coalesce(vararg options: T?): T? = options.firstOrNull { it != null }
fun <T: Any> Collection<T?>.coalesce(): T? = this.firstOrNull { it != null }
Örnek kullanım:
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"
Diğer varyasyonlar
... Başka varyasyonlar da var, ancak daha fazla spesifikasyonla bu daraltılabilir.