我是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。谢谢。
答案 0 :(得分:3)
错误告诉您无法保证endtrip
在该行代码中不为空。原因是endtrip
是var
。它可以被其他线程变异,即使你在使用该变量之前进行了空检查。
以下是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)
您收到该错误的原因是智能投射和使用var
。 var
是可变的,因此在代码中的任何位置都可以更改它。 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
}