Respuestas:
Puede usar la let
función -como esta:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Tenga en cuenta que debe llamar a la run
función solo si necesita un bloque de código. Puede eliminar el run
-block si solo tiene un delineador después del elvis-operator ( ?:
).
Tenga en cuenta que el run
bloque se evaluará si b
es nulo o si let
-block se evalúa comonull
.
Debido a esto, normalmente solo quieres una if
expresión.
val a = if (b == null) {
// ...
} else {
// ...
}
En este caso, el else
-block solo se evaluará si b
no es nulo.
a
aún no está definido dentro del alcance de let
y run
. Pero puede acceder al valor de b
dentro del let
con el parámetro implícitoit
. Esto tiene el mismo propósito, supongo.
a
antes de esos bloques de código. Y a
se puede acceder al interior.
a
? Si es así b
, entonces it
tiene exactamente el mismo propósito. ¿Se reasigna a
con el resultado del val
-bloque?
it
desde dentro del let
bloque. El resultado del bloque let
o run
se asignará a a
. El resultado es la última expresión del bloque. Utiliza la tarea después de que let
/ run
ha terminado, al igual que lo hace con cualquier otra tarea normal.
Primero asegurémonos de entender la semántica del idioma Swift proporcionado:
if let a = <expr> {
// then-block
}
else {
// else-block
}
Significa esto: "si el <expr>
resultado es un opcional no nulo, ingrese el then
-bloque con el símbolo a
ligado al valor no envuelto. De lo contrario, ingrese al else
bloque.
Especialmente tenga en cuenta que a
está limitado solo dentro del then
bloque . En Kotlin puede obtenerlo fácilmente llamando
<expr>?.also { a ->
// then-block
}
y puede agregar un else
bloque como este:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Esto da como resultado la misma semántica que el modismo Swift.
Mi respuesta es totalmente una imitación de los demás. Sin embargo, no puedo entender su expresión fácilmente. Así que supongo que sería bueno dar una respuesta más comprensible.
En rápido:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
En Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
let
lugar de also
significa que el run
bloque se ejecutará siempre que el let
bloque regrese null
, que no es lo que queremos.
A diferencia de Swift, no es necesario desenvolver el opcional antes de usarlo en Kotlin. Podríamos simplemente verificar si el valor no es nulo y el compilador rastrea la información sobre la verificación que realizó y permite usarla sin empaquetar.
En Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
En Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Consulte Documentación: (seguridad nula) para más casos de uso
if let
declaración.La Optional Binding
(llamada if-let
declaración) de Swift se usa para averiguar si un opcional contiene un valor y, de ser así, para hacer que ese valor esté disponible como una constante o variable temporal. Entonces, una Optional Binding
para la if-let
declaración es la siguiente:
if-let
Declaración de Swift :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
En Kotlin, como en Swift, para evitar bloqueos causados por intentar acceder a un valor nulo cuando no se espera, se proporciona una sintaxis específica (como b.let { }
en el segundo ejemplo) para desenvolver correctamente nullable types
:
Equivalente de Kotlin 1 de la
if-let
declaración de Swift :
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
La let
función de Kotlin , cuando se usa en combinación con el operador de llamada segura ?:
, proporciona una forma concisa de manejar expresiones que aceptan valores NULL.
Equivalente de Kotlin 2 (función let en línea y operador de Elvis) de la
if-let
declaración de Swift :
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let
declaración.guard-let
declaración en Swift es simple y poderosa. Comprueba si hay alguna condición y si se evalúa como falsa, entonces se else
ejecuta la declaración que normalmente saldrá de un método.
Exploremos la
guard-let
declaración de Swift :
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
Efecto similar de Kotlin de la
guard-let
declaración de Swift :
A diferencia de Swift, en Kotlin, no hay ninguna declaración de guardia . Sin embargo, puede usar Elvis Operator
- ?:
para obtener un efecto similar.
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
Espero que esto ayude.
A continuación, se explica cómo ejecutar código solo cuando name
no es nulo:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
let
hace, pero la pregunta es sobre la else
estrategia que se ejecuta si el objeto en el que let
se llama es null
. Swift lo tiene de una manera más natural (discutible). Pero después de haber hecho mucho a Kotlin y Swift, desearía que Kotlin tuviera un desenvolvimiento simple como lo hace Swift.
Aquí está mi variante, limitada al caso muy común "si no nulo".
En primer lugar, defina esto en alguna parte:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
Probablemente debería serlo internal
, para evitar conflictos.
Ahora, convierta este código Swift:
if let item = obj.item {
doSomething(item)
}
A este código de Kotlin:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Tenga en cuenta que, como siempre con los bloques en Kotlin, puede eliminar el argumento y usar it
:
ifNotNull(obj.item) {
doSomething(it)
}
Pero si el bloque tiene más de 1-2 líneas, probablemente sea mejor ser explícito.
Esto es tan similar a Swift como pude encontrar.
Hay una forma similar en kotlin de lograr el estilo de Swift if-let
if (val a = b) {
a.doFirst()
a.doSecond()
}
También puede asignar varios valores que aceptan valores NULL
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
Este tipo de enfoque será más adecuado si los valores que aceptan valores NULL se utilizan más de una vez. En mi opinión, ayuda desde el aspecto del rendimiento porque el valor anulable se comprobará solo una vez.
fuente: Discusión de Kotlin
Estoy agregando esta respuesta para aclarar la respuesta aceptada porque es demasiado grande para un comentario.
El patrón general aquí es que puede usar cualquier combinación de las funciones de alcance disponibles en Kotlin separadas por el operador de Elvis de esta manera:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
Por ejemplo:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
a
No se puede acceder al interiorlet
y alrun
bloque.