Smart Cast para BootsrapButton es imposible porque endtrip es una propiedad mutable que ha cambiado en este momento

Soy nuevo en Kotlin. Tengo un proyecto de Android que opté por convertir a kotlin. Este es mi pedazo de código.

import com.beardedhen.androidbootstrap.BootstrapButton class EndTrip : AppCompatActivity(){ internal var endtrip: BootstrapButton ?= null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_end_trip) endtrip.setOnClickListener(View.OnClickListener { //Some code here } } } 

Pero obtengo este error en el endtrip

El lanzamiento inteligente a BootsrapButton es imposible porque la propiedad de final de recorrido es mutable y ha cambiado en este momento

Una pregunta similar ha sido respondida aquí, pero no puedo encontrar la solución. Estoy usando beardedhen Android Bootstrap Library . Gracias.

El error le indica que no puede garantizar que el endtrip no sea nulo en esa línea de código. La razón es que endtrip es una var . Puede ser mutado por otro hilo, incluso si haces una comprobación nula justo antes de usar esa variable.

Aquí está la explicación del documento oficial :

Tenga en count que las versiones inteligentes no funcionan cuando el comstackdor no puede garantizar que la variable no pueda cambiar entre la verificación y el uso. Más específicamente, los moldes inteligentes son aplicables de acuerdo con las siguientes reglas:

  • val variables locales – siempre;
  • properties val – si la propiedad es privada o interna o la verificación se realiza en el mismo module donde se declara la propiedad. Los lanzamientos inteligentes no son aplicables a las properties abiertas o las properties que tienen getters personalizados;
  • variables locales var – si la variable no se modifica entre el cheque y el uso y no se captura en una lambda que lo modifique;
  • properties var – nunca (porque la variable puede ser modificada en cualquier momento por otro código).

La solución más simple es usar un operador de llamada segura ?.

 endtrip?.setOnClickListener(View.OnClickListener { //Some code here } 

Lectura sugerida: en Kotlin, ¿cuál es la forma idiomática de tratar con valores que aceptan nulos, referencerlos o convertirlos?

val es la estática, var es la mutable. kotlin prefiere todo lo estático aún más en el lugar donde lo llamaste.

Solo para aclarar un poco, a Kotlin solo le gusta que uses var dentro de un método, no le gusta en general. Quiere val allá arriba.

val es una variable inmutable var es mutable.

He resuelto el problema. Eliminé la statement global de endtrip y la inicialicé en el método onCreate como se muestra a continuación.

 import com.beardedhen.androidbootstrap.BootstrapButton class EndTrip : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_end_trip) var endtrip: BootstrapButton = findViewById(R.id.endtrip) as BootstrapButton endtrip.setOnClickListener(View.OnClickListener { //Some code here } } } 

Pero mi preocupación es ¿qué pasa si quiero usar una variable en otros methods?

La razón por la que recibe ese error se debe a la casting inteligente y al uso de var . var es mutable, por lo que en cualquier punto de su código, se puede cambiar. Kotlin no puede garantizar eso, el valor al que se endtrip el endtrip se puede convertir en BootstrapButton por lo tanto, el error. En la documentation bajo Smart Cast, enumera varias instancias cuando el casting inteligente no puede ser posible. Puedes encontrarlos aquí .

Para que su código funcione, deberá cambiarlo a este

 val endtrip: BootstrapButton ?= null 

Con esto, Kotlin puede estar seguro de que su variable endtrip no cambiará y puede convertirlo a BootstrapButton con éxito.

Editar: como quiera reasignar endtrip, podría hacer algo como esto:

 var endtrip: BootstrapButton ?= null val immutableEndtrip = endtrip // you can definitely use a different variable name if(immutableEndtrip !=null) { endtrip = findViewById(R.id.endtrip) as BootstrapButton } 
  • Cuando se utiliza Java / Kotlin para la progtwigción, se recomienda utilizar la recursion de queue o la versión iterativa. ¿Hay alguna diferencia en el performance?
  • Kotlin enlazó la incoinheritance de las references invocables
  • Kotlin VS Scala: Implementar methods con parameters constructor primarios
  • Cómo instalar un controller de clics en una vista de list dinámica (en tornadofx)
  • Temporizador RxJava2 y combinar
  • Error: ejecución fallida para la tarea ': app: kaptDemoTestingDebugKotlin'
  • Kotlin - Jackson ignora los valores nulos
  • TornadoFX reemplaza el layoutChildren en la región
  • Intercambio de un nodo en Guava MutableValueGraph
  • Kotlin @JvmStatic y anulación accidental en un object complementario
  • ¿De dónde vienen los tres contenedores de testing?