Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

329
Views
¿Cómo puedo verificar si un conjunto de funciones devuelve un valor no nulo, en una sola expresión?

Supongamos que tengo tres funciones foo , bar , baz , todas las cuales devuelven tipos anulables.

 fun foo(): Int? = 1 fun bar(): Int? = 2 fun baz(): Int? = 3

Quiero llamarlos, y si todos devuelven un valor no nulo, quiero calcular un valor a partir de sus valores de retorno.

Podría hacer esto con declaraciones , como esta:

 val x = foo() val y = bar() val z = baz() val result = if (x != null && y != null && z != null) x + y + z else null

Sin embargo, no me gusta el hecho de que tengo que declarar 3 variables adicionales a las que aún puedo acceder después. Al tener 3 declaraciones adicionales como esta, también significa que no puedo usar funciones con cuerpo de expresión, si estuviera escribiendo una función que devuelve result .

Si uso let s en su lugar:

 val result = foo()?.let { x -> bar()?.let { y -> baz()?.let { z -> x + y + z } } }

Esto crea un anidamiento profundo. Si fuera solo una función, esto habría estado bien, pero con 3 funciones o más, esto hace que mi intención de "llamar a estas tres funciones, si no son nulas, sumarlas" no sea clara.

¿Cómo puedo escribir esto de una manera que transmita claramente mi intención, pero también convirtiéndolo en una sola expresión?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

val result = listOf(foo(), bar(), baz()) .reduce { acc, i -> when { acc == null || i == null -> null else -> acc + i } }

O como función:

 fun <T> apply(operation: (T, T) -> T, vararg values: T?): T? { return values .reduce { acc, i -> when { acc == null || i == null -> null else -> operation(acc, i) } } } val result = apply({ x, y -> x + y }, foo(), bar(), baz())
over 4 years ago · Santiago Trujillo Report

0

Puede filtrar todos los valores null y solo aplicar una operación en la lista, si no se redujo en tamaño, por ejemplo:

 fun sumIfNoneNull(values: List<Int?>): Int? = values .filterNotNull() .takeIf { it.size == values.size } ?.sum()

Uno puede generalizar esto aún más, por ejemplo:

 fun <T, R> List<T>.foldIfNoneNull( initial: R, operation: (acc: R, T) -> R ): R? = this .filterNotNull() .takeIf { nonNullList -> nonNullList.size == this.size } ?.fold(initial, operation)

Puede usar esto como cualquier otro fold , por ejemplo:

 listOf(foo(), bar(), baz()).foldIfNoneNull(0) { acc, cur -> acc + cur }
over 4 years ago · Santiago Trujillo Report

0

Si son de diferentes tipos, creo que necesita escribir sus propias funciones auxiliares como estas (se necesitan diferentes sobrecargas para diferentes números de parámetros, porque no hay otra forma de que el compilador conozca los tipos de argumentos):

 inline fun <T : Any, U : Any, R> ifAllNotNull(t: T?, u: U?, block: (t: T, u: U) -> R): R? { return when { t != null && u != null -> block(t, u) else -> null } } inline fun <T : Any, U : Any, V : Any, R> ifAllNotNull(t: T?, u: U?, v: V?, block: (t: T, u: U, v: V) -> R): R? { return when { t != null && u != null && v != null -> block(t, u, v) else -> null } }
 val result = ifAllNotNull(foo(), bar(), baz()) { x, y, z -> x + y + z }

Tenga en cuenta que los tres parámetros se evaluarán antes de comprobar si alguno es nulo.


O si desea hacer lo que describió (ocultar las tres variables después del cálculo del resultado) usando solo funciones de biblioteca estándar, puede usar run para limitar el alcance de las variables temporales:

 val result = run { val x = foo() val y = bar() val z = baz() if (x != null && y != null && z != null) x + y + z else null }

Esto también le daría la oportunidad de hacer un cortocircuito si lo desea:

 val result = run { val x = foo() ?: return@run null val y = bar() ?: return@run null val z = baz() ?: return@run null x + y + z }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!