Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

327
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda