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 } 
  • Prueba JUnit con KOTLIN android studio
  • El adaptador de enlace Picasso 'se ha filtrado una connection'
  • ¿Cómo puedo ejecutar las testings de kotlintest con gradle?
  • @CreationTimestamp y @UpdateTimestamp no funcionan en Kotlin
  • Ejecute testings junit escritas en Kotlin con la anotación @category
  • kapt2 y butterknife producen error de pelusa: recurso esperado de tipo id
  • El método en línea de Kotlin no es visible a less que se extienda la class
  • Kotlin: ¿"eso" asignable?
  • Kotlin y Gradle - Lectura desde stdio
  • Cómo implementar en jna una estructura sizeof () con un tipo de unión
  • cómo especificar el order de plugin de comstackdor maven