ternary-operator - for - kotlin ternary operator
Operador Condicional Ternario Kotlin (28)
Ejemplo: var energy: Int = data? .get (position)? energy? .toInt ()?: 0
En kotlin, si está usando ?: Funcionará como si la instrucción devolviera un valor nulo y luego ?: 0 tomará 0 o lo que sea que tenga escrito en este lado.
¿Cuál es el equivalente de esta expresión en Kotlin?
a ? b : c
Este no es un código válido en Kotlin.
En Kotlin,
if
es una expresión, es decir, devuelve un valor. Por lo tanto, no hay un operador ternario(condition ? then : else)
, porque ordinario si funciona bien en este rol. fuente manual desde aquí
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
En Kotlin, no hay operador ternario .
En Kotlin, si es una expresión, es decir, devuelve un valor.
Por lo tanto, no hay un operador ternario (condición? Luego: else), porque ordinario si funciona bien en este rol.
Equivalente en Kotlin
var a = if (a) b else c
Documento de referencia : Flujo de control: si, cuando, por, mientras
Kotlin tiene expresiones
En Kotlin, muchas declaraciones de control que incluyen if
, when
o incluso try
pueden usarse como expresiones . Esto significa que pueden tener un resultado que puede asignarse a una variable, devolverse desde una función, etc.
Sintácticamente, sin necesidad de operador ternario.
Como resultado, Kotlin no necesita el operador ternario .
if (a) b else c
es lo que puede usar en lugar de la expresión Java a ? b : c
a ? b : c
.
Creo que la idea es que esta última sea menos legible, ya que todos saben qué pasa ifelse
lo hace ? :
? :
es más bien inconveniente si no estás familiarizado con la sintaxis ya. Aunque debo admitir que a menudo extraño al operador ternario más conveniente.
Otras alternativas
cuando
También puede ver mucho when
construye cuando se verifican las condiciones en Kotlin. También es una forma de expresar las cascadas if-else de una manera alternativa. Lo siguiente corresponde a tu ejemplo.
when(a) {
true -> b
false -> c
}
Extensiones
Como lo demuestran muchos buenos ejemplos ( Kotlin Ternary Conditional Operator ) en las otras respuestas, las extensiones también pueden ser un camino a seguir.
¿Por qué uno usaría algo como esto?
when(a) {
true -> b
false -> b
}
cuando realmente puedes usar algo como esto ( a
es booleano en este caso):
when {
a -> b
else -> b
}
Algunos casos de esquina no mencionados en otras respuestas.
Desde la aparición de takeIf en Kotlin 1.1 el operador ternario a ? b : c
a ? b : c
también puede expresarse así:
b.takeIf { a } ?: c
Esto se vuelve aún más corto en el caso de que c sea null
:
b.takeIf { a }
También tenga en cuenta que en el mundo de Java, el value != null ? value : defaultValue
nulo se comprueba como value != null ? value : defaultValue
value != null ? value : defaultValue
traduce en ideomatic Kotlin a solo value ?: defaultValue
.
Similar a != null ? b : c
a != null ? b : c
se puede traducir a a?.let { b } ?: c
.
Con las siguientes funciones de infijo puedo cubrir muchos casos de uso comunes de la misma manera que se puede hacer en Python:
class TestKotlinTernaryConditionalOperator {
@Test
fun testAndOrInfixFunctions() {
Assertions.assertThat(true and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(false and "yes" or "no").isEqualTo("no")
Assertions.assertThat("A" and "yes" or "no").isEqualTo("yes")
Assertions.assertThat("" and "yes" or "no").isEqualTo("no")
Assertions.assertThat(1 and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(0 and "yes" or "no").isEqualTo("no")
Assertions.assertThat(Date() and "yes" or "no").isEqualTo("yes")
@Suppress("CAST_NEVER_SUCCEEDS")
Assertions.assertThat(null as Date? and "yes" or "no").isEqualTo("no")
}
}
infix fun <E> Boolean?.and(other: E?): E? = if (this == true) other else null
infix fun <E> CharSequence?.and(other: E?): E? = if (!(this ?: "").isEmpty()) other else null
infix fun <E> Number?.and(other: E?): E? = if (this?.toInt() ?: 0 != 0) other else null
infix fun <E> Any?.and(other: E?): E? = if (this != null) other else null
infix fun <E> E?.or(other: E?): E? = this ?: other
Cuando trabaje con apply (), déjese parecer muy útil cuando se trata de operaciones ternarias, ya que es más elegante y le da espacio.
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
Echa un vistazo a los documentos :
En Kotlin, si es una expresión, es decir, devuelve un valor. Por lo tanto, no hay un operador ternario (condición? Luego: else), porque ordinario si funciona bien en este rol.
En Kotlin, if
declaraciones son expresiones. Entonces el siguiente código es equivalente:
if (a) b else c
La distinción entre expresión y declaración es importante aquí. En Java / C # / JavaScript, if
forma una declaración, significa que no se resuelve en un valor. Más concretamente, no puedes asignarlo a una variable.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Si viene de un lenguaje en el que if
es una afirmación, esto puede parecer poco natural, pero ese sentimiento debería desaparecer pronto.
Java
int temp = a ? b : c;
Equivalente a Kotlin:
var temp = if (a) b else c
No hay operador ternario en kotlin, ya que el bloque if else
devuelve valor
entonces, puede hacer: val max = if (a > b) a else b
lugar de max = (a > b) ? b : c
de java max = (a > b) ? b : c
max = (a > b) ? b : c
También podemos usar when
construcción, también devuelve valor:
val max = when(a > b) {
true -> a
false -> b
}
Aquí está el enlace para la documentación de kotlin: Flujo de control: si, cuándo, por, mientras
No hay operador ternario en Kotlin. Parece problemático a primera vista. Pero piense que podemos hacerlo con la instrucción inline if else porque esta es la expresión aquí. Simplemente tenemos que hacer ...
var number = if(n>0) "Positive" else "Negetive"
Aquí podemos más si bloqueamos tantos como necesitemos. Me gusta-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Así que esta línea es tan simple y mucho más legible que el operador ternario. cuando usamos más de un operador ternario en java parece horrible. Pero aquí tenemos una sintaxis clara. Incluso podemos escribirlo en múltiples líneas también.
No hay un operador ternario en Kotlin, los más cerrados son los siguientes dos casos,
- Si otra cosa como declaración de expresión
val a = true if(a) print("A is true") else print("A is false")
- Operador de elvis
Si la expresión a la izquierda de?: No es nula, el operador de elvis la devuelve, de lo contrario, devuelve la expresión a la derecha. Tenga en cuenta que la expresión del lado derecho solo se evalúa si el lado izquierdo es nulo.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
No hay una operación ternaria en Kotlin, pero hay algunas maneras divertidas de solucionarlo. Como otros han señalado, una traducción directa a Kotlin se vería así:
val x = if (condition) result1 else result2
Pero, personalmente, creo que puede ser un poco abarrotado y difícil de leer. Hay algunas otras opciones integradas en la biblioteca. Puedes usar takeIf {} con un operador de elvis:
val x = result1.takeIf { condition } ?: result2
Lo que sucede allí es que el comando takeIf {} devuelve su resultado1 o nulo, y el operador de elvis se encarga de la opción nula. Hay algunas opciones adicionales, takeUnless {}, por ejemplo:
val x = result1.takeUnless { condition } ?: result2
El lenguaje es claro, ya sabes lo que está haciendo.
Si es una condición de uso común, también podría hacer algo divertido como usar un método de extensión en línea. Supongamos que queremos realizar un seguimiento de la puntuación de un juego como un Int, por ejemplo, y queremos devolver siempre 0 si no se cumple una condición determinada:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Ok, eso parece feo. Pero considera cómo se ve cuando se usa:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Como puede ver, Kotlin ofrece mucha flexibilidad en la forma en que elige expresar su código. Hay innumerables variaciones de mis ejemplos y probablemente formas que aún no he descubierto. ¡Espero que esto ayude!
Otro enfoque corto para usar
val value : String = "Kotlin"
value ?: ""
Aquí, el propio kotlin comprueba el valor nulo y, si es nulo, pasa el valor de la cadena vacía.
Otro enfoque interesante sería utilizar when
:
when(a) {
true -> b
false -> b
}
Puede ser bastante útil en algunos escenarios más complejos. Y honestamente, es más legible para mí que if ... else ...
Para mí utilizo las siguientes funciones de extensión:
fun T?.or<T>(default: T): T = if (this == null) default else this
fun T?.or<T>(compute: () -> T): T = if (this == null) compute() else this
Primero se devolverá el valor predeterminado proporcionado en caso de que el objeto sea igual a nulo. En segundo lugar se evaluará la expresión proporcionada en lambda en el mismo caso.
Uso:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Personalmente, para mí, el código anterior es más legible que if
incluye en la construcción.
Podría definir su propia Boolean
extensión Boolean
que devuelva null
cuando el Boolean
sea false
para proporcionar una estructura similar al operador ternario:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Esto haría una a ? b : c
a ? b : c
expresión a ? b : c
traduce a a then b ?: c
, así:
println(condition then "yes" ?: "no")
Actualización: Pero para hacer un cambio condicional más parecido a Java, necesitarás algo así.
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
preste atención a la lambda. su cálculo de contenido debe posponerse hasta que nos aseguremos de que la condition
sea true
Este parece torpe, es por eso que existe una alta demanda de solicitud para portar el operador ternario de Java a Kotlin
Puede usar var a= if (a) b else c
en lugar del operador ternario.
Otro buen concepto de kotlin es Elvis operater. No es necesario marcar nulo cada vez.
val l = b?.length ?: -1
Esto devolverá la longitud si b no es nulo, de lo contrario ejecuta la declaración del lado derecho.
Puedes hacerlo de muchas maneras en Kotlin.
Usando si
if(a) b else c
Usando cuando
when (a) { true -> print("value b") false -> print("value c") else -> { print("default return in any other case") } }
Seguridad nula
val a = b ?: c
Puedes usar la expresión if
para esto en Kotlin. En Kotlin if
es una expresión con un valor de resultado. Así que en Kotlin podemos escribir.
fun max(a: Int, b: Int) = if (a > b) a else b
Y en Java podemos lograr lo mismo pero con código más grande.
int max(int a, int b) {
return a > b ? a : b
}
Según la documentación de Kotlin, uso el siguiente código:
val max = if (a > b) a else b
Y:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
Si desea obtener más información, consulte este enlace: Flujo de control: si, cuándo, por, mientras
como citó Drew Noakes, kotlin usa la instrucción if como expresión, por lo que el operador condicional ternario ya no es necesario,
pero con la función de extensión y la sobrecarga de infijo, puede implementarlo usted mismo, aquí hay un ejemplo
infix fun <T> Boolean.then(value: T?) = TernaryExpression(this, value)
class TernaryExpression<out T>(val flag: Boolean, val truly: T?) {
infix fun <T> or(falsy: T?) = if (flag) truly else falsy
}
entonces úsalo así
val grade = 90
val clazz = (grade > 80) then "A" or "B"
cuando reemplaza el operador de conmutador de C-como idiomas. En la forma más simple se ve así
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
no hay un operador ternario en Kotlin, para eso hay if expresión:
var d = if (a) b else c
use la sentencia condicional if-else o el operador de la siguiente manera
when(a) {
true -> b
false -> b
}
var a:Int=20
var b:Int=5
val c:Int=15
var d=if(a>b)a else c
print("Output is: $d")