Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

340
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda