智能投到BootsrapButton是不可能的,因为endtrip是这个时候改变了的可变属性

我是Kotlin新手。 我有一个android项目,我选择转换为kotlin。 这是我的一段代码。

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 } } } 

但是,我得到这个错误的结束

智能投到BootsrapButton是不可能的,因为endtrip是这个时候已经改变的可变属性

一个类似的问题已经在这里回答,但我不能找出解决方案。 我正在使用大胆的Android Bootstrap库 。 谢谢。

错误告诉你,你不能保证在这行代码中endtrip不为空。 原因是endtrip是一个var 。 即使您在使用该变量之前执行空检查,也可以由其他线程进行变异。

这是官方文件的解释:

请注意,当编译器无法保证变量不能在检查和使用之间变化时,智能转换不起作用。 更具体地说,智能演员适用于以下规则:

  • val局部变量 – 总是;
  • val属性 – 如果属性是私有的或者内部的,或者在声明属性的相同模块中执行检查。 智能转换不适用于打开属性或具有自定义获取者的属性;
  • var局部变量 – 如果变量在检查和用法之间没有被修改,并且没有在修改它的lambda中被捕获;
  • var属性 – 从不(因为变量可以随时由其他代码修改)。

最简单的解决方案是使用安全的呼叫运营商?.

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

建议阅读: 在Kotlin中,处理可空值的惯用方法是什么,引用或转换它们

val是静态的,var是可变的。 kotlin更喜欢静态的东西,甚至在你称之为的地方更是如此。

只是为了澄清一点,Kotlin只是真的喜欢你在一个方法里面使用var,它不喜欢它的主要。 它要在那里。

val是一个不可变的变量var是可变的。

我已经弄清楚了这个问题。 我删除了endtrip的全局声明,并在onCreate方法中初始化它,如下所示。

 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 } } } 

但是我的担心是如果我想在其他方法中使用一个变量呢?

您收到该错误的原因是由于智能铸造和使用varvar是可变的,所以在你的代码中的任何一点,它都可以被改变。 Kotlin不能保证,结束的值将被转换到BootstrapButton从而出错。 在智能转换下的文档中,它列出了智能转换无法进行的各种情况。 你可以在这里找到它们。

为了使你的代码工作,你将不得不改变它

 val endtrip: BootstrapButton ?= null 

有了这个,Kotlin放心,你的endtrip变量不会改变,并且可以成功将它转换为BootstrapButton。

编辑:因为你想重新分配endtrip,你可以做这样的事情:

 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 }