Y el novato de Kotlin pregunta: "¿por qué no se compila el siguiente código?":
var left: Node? = null
fun show() {
if (left != null) {
queue.add(left) // ERROR HERE
}
}
La conversión inteligente a 'Nodo' es imposible, porque 'izquierda' es una propiedad mutable que podría haberse cambiado en este momento
Entiendo que left
es una variable mutable, pero estoy comprobando explícitamente left != null
y left
es de tipo, Node
¿por qué no se puede convertir de forma inteligente en ese tipo?
¿Cómo puedo arreglar esto con elegancia? :)
n.left?.let { queue.add(it) }
creo?Respuestas:
Entre la ejecución de
left != null
yqueue.add(left)
otro hilo podría haber cambiado el valor deleft
anull
.Para evitar esto, tiene varias opciones. Aquí están algunas:
Use una variable local con conversión inteligente:
Use una llamada segura como una de las siguientes:
Use el operador Elvis con
return
para regresar temprano de la función de cierre:Tenga en cuenta que
break
ycontinue
puede usarse de manera similar para las comprobaciones dentro de los bucles.fuente
Node
clase definida en la versión original de la pregunta que tenía un fragmento de código más complicado enn.left
lugar de simplementeleft
. He actualizado la respuesta en consecuencia. Gracias.val
para cada unavar
, anidar varias?.let
declaraciones o usar varias?: return
declaraciones según su función. por ejMyAsyncTask().execute(a1 ?: return, a2 ?: return, a3 ?: return)
. También puede probar una de las soluciones para una "variable múltiple let" .1) También puede usar
lateinit
Si seguro realiza su inicialización más adelanteonCreate()
o en otro lugar.Utilizar este
En lugar de esto
2) Y hay otra forma de usar el
!!
final de variable cuando lo usas asífuente
Hay una cuarta opción además de las de la respuesta de mfulton26.
Al usar el
?.
operador, es posible llamar a métodos y campos sin tener que lidiarlet
o usar variables locales.Algún código para el contexto:
Funciona con métodos, campos y todas las otras cosas que intenté para que funcione.
Entonces, para resolver el problema, en lugar de tener que usar conversiones manuales o usar variables locales, puede usar
?.
para llamar a los métodos.Como referencia, esto se probó en Kotlin
1.1.4-3
, pero también se probó en1.1.51
y1.1.60
. No hay garantía de que funcione en otras versiones, podría ser una nueva característica.El uso del
?.
operador no se puede usar en su caso, ya que el problema es una variable pasada. El operador de Elvis se puede usar como alternativa, y probablemente sea el que requiera la menor cantidad de código. Sincontinue
embargo, en lugar de usar ,return
también podría usarse.El uso de la conversión manual también podría ser una opción, pero esto no es nulo seguro:
Es decir, si la izquierda ha cambiado en un hilo diferente, el programa se bloqueará.
fuente
left
y noqueue
. Necesito verificar esto, editaré la respuesta en un minutoLa razón práctica por la que esto no funciona no está relacionada con los hilos. El punto es que
node.left
se traduce efectivamente ennode.getLeft()
.Este captador de propiedades se puede definir como:
Por lo tanto, dos llamadas podrían no devolver el mismo resultado.
fuente
Cambiar
var left: Node? = null
alateinit var left: Node
. Problema resuelto.fuente
Hacer esto:
Cuál parece ser la primera opción proporcionada por la respuesta aceptada, pero eso es lo que estás buscando.
fuente
Para que haya un Smart Cast de las propiedades, el tipo de datos de la propiedad debe ser la clase que contiene el método o comportamiento al que desea acceder y NO que la propiedad sea del tipo de la superclase.
por ejemplo, en Android
Ser:
Solución:
Uso:
GL
fuente
Su solución más elegante debe ser:
Entonces no tiene que definir una variable local nueva e innecesaria, y no tiene nuevas aserciones o conversiones (que no sean SECAS). Otras funciones de alcance también podrían funcionar, así que elija su favorito.
fuente
Intente usar el operador de aserción no nulo ...
fuente
Cómo lo escribiría:
fuente