Smart Cast a 'Tipo' es imposible, porque 'variable' es una propiedad mutable que podría haber cambiado en este momento

Y el novato de Kotlin pregunta: "¿por qué no se comstackrá el siguiente código?" :

var left: Node? = null fun show() { if (left != null) { queue.add(left) // ERROR HERE } } 

El lanzamiento inteligente a 'Nodo' es imposible, porque 'izquierda' es una propiedad mutable que podría haberse cambiado en este momento

Veo que la variable mutable left es, pero estoy comprobando explícitamente left != null y left es de tipo Node entonces ¿por qué no puede ser smart-casted para ese tipo?

¿Cómo puedo arreglar esto elegantemente? 🙂

Entre la ejecución de n.left != null queue.add(n.left) y queue.add(n.left) otro hilo podría haber cambiado el valor de n.left a null .

Para solucionar esto, tiene varias opciones. Aquí están algunas:

  1. Usa una variable local con smart cast:

     val left = n.left if (left != null) { queue.add(left) } 
  2. Use una llamada segura como una de las siguientes:

     n.left?.let { left -> queue.add(left) } n.left?.let { queue.add(it) } n.left?.let(queue::add) 
  3. Utilice el operador de Elvis con un salto al siguiente paso del bucle while encierra:

     queue.add(n.left ?: continue) 

Hay una cuarta opción además de las que están en la respuesta de mfulton26.

Al usar el ?. Es posible llamar tanto a los methods como a los campos sin tener que lidiar con let o usar variables locales.

Algunos códigos para el context:

 var factory: ServerSocketFactory = SSLServerSocketFactory.getDefault(); socket = factory.createServerSocket(port) socket.close()//smartcast impossible socket?.close()//Smartcast possible. And works when called 

Funciona con methods, campos y todas las otras cosas que intenté para que funcione.

Entonces, para resolver el problema, en lugar de tener que usar moldes manuales o usar variables locales, puede usar ?. para llamar a los methods.

Como reference, esto se probó en Kotlin 1.1.4-3 , pero también se probó en 1.1.51 y 1.1.60 . No hay garantía de que funcione en otras versiones, podría ser una característica nueva.

Usando el ?. El operador no puede usarse en su caso, ya que es una variable pasada el problema. El operador de Elvis se puede utilizar como alternativa, y es probablemente el que requiere la menor cantidad de código. Sin embargo, en lugar de continue , el return también podría ser utilizado.

Usar el lanzamiento manual también podría ser una opción, pero esto no es seguro.

 queue.add(left as Node); 

Es decir, si la izquierda ha cambiado en un hilo diferente, el progtwig se bloqueará.

  • Consultar Androids ContactsContract en Kotlin
  • ¿Por qué se eliminó el bucle indexado en Kotlin?
  • Ejemplo de cuándo deberíamos usar ejecutar, dejar, aplicar, también y con Kotlin
  • ¿Es posible inicializar una propiedad y afirmarla?
  • Constructor de class de datos con dos constructores diferentes en Kotlin
  • Kotlin: onGlobalLayout no se llama
  • No se pudo encontrar kotlin-reflect.jar (org.jetbrains.kotlin: kotlin-reflect: 1.1.3-2) en android studio 3.0
  • (número + "Es más de 5") No se está ejecutando "Error de concatenación"
  • Cómo establecer pivotes dynamics para girar la animation
  • ¿Cómo obtengo las funciones declaradas de una class Kotlin (KClass en M12)?
  • Revisión de código La mejor manera de uso ShanetworkingPreferences solving MemoryLeak