对BootsrapButton的智能转换是不可能的,因为endtrip是可变属性,此时已更改

时间:2017-08-05 05:27:25

标签: android kotlin

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

但是我在endtrip上得到了这个错误

  

对于BootsrapButton的智能转换是不可能的,因为endtrip是可变的   此时已更改的财产

类似的问题已被回答here但我无法找出解决方案。我正在使用beardedhen Android Bootstrap Library。谢谢。

4 个答案:

答案 0 :(得分:3)

错误告诉您无法保证endtrip在该行代码中不为空。原因是endtripvar。它可以被其他线程变异,即使你在使用该变量之前进行了空检查。

以下是official document's解释:

  

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

     
      
  • val 局部变量 - 始终;
  •   
  • val 属性 - 如果属性为private或internal,或者在声明属性的同一模块中执行检查。智能演员表不适用于打开属性或具有自定义getter的属性;
  •   
  • var 局部变量 - 如果在检查和使用之间没有修改变量,并且没有在修改它的lambda中捕获;
  •   
  • var 属性 - 从不(因为其他代码可以随时修改变量)。
  •   

最简单的解决方案是使用安全调用运算符?.

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

建议阅读:In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them

答案 1 :(得分:0)

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

为了澄清一点,Kotlin只是非常喜欢你在一个方法中使用var,它在主要方面并不喜欢它。它想要val那里。

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

答案 2 :(得分:0)

我已经找到了问题所在。我删除了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
}
}
}

但如果我想在其他方法中使用变量,我担心的是什么?

答案 3 :(得分:0)

您收到该错误的原因是智能投射和使用varvar是可变的,因此在代码中的任何位置都可以更改它。 Kotlin无法保证endtrip将被更改为的值可以转换为BootstrapButton因此错误。在智能广播下的文档中,它列出了无法进行智能投射时的各种实例。你可以找到它们here

要使代码正常工作,您必须将其更改为

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
}