我有下面的代码。它是 Kotlin 。知道为什么来自 textToSpeech.setLanguage(Locale.UK)
的 textToSpeech
告诉我们没有为 textToSpeech
解析引用吗?
val textToSpeech = TextToSpeech(
applicationContext,
object : TextToSpeech.OnInitListener {
override fun onInit(status: Int) {
if (status == TextToSpeech.SUCCESS) {
textToSpeech.setLanguage(Locale.UK)
}
}
})
一开始我以为是idea kotlin插件的bug,但是好像真的编译不出来
最佳答案
Kotlin 强化了变量初始化策略,现在禁止在其初始化程序中引用变量,即使在 lambda 和对象表达式中也是如此,这似乎是合理的:想象在变量赋值之前立即调用 lambda。
对于您的情况,我可以建议使用 object expression 作为解决方法在这个相当繁琐的结构中:
val textToSpeech = object {
val value: TextToSpeech get() = inner
private val inner = TextToSpeech(
applicationContext,
{ value.setLanguage(Locale.UK) }
)
}.value
这将初始化一个带有 inner
的匿名对象,该对象可以通过 value
属性接受。请注意,inner
初始化程序使用 value
属性。然后value
被提取出来,可以使用了。
但请记住,这个技巧是不安全的:在运行时,在分配 inner
之前使用 value
(例如在 TextToSpeech
构造函数中)将抛出 NullPointerException
。
另外,我使用 SAM conversion 将 OnInitListener
替换为 lambda。简而言之,但仍然可以在那里使用对象表达式。
UPD:检查this question我努力推广这种方法。使用它,你可以写
val textToSpeech = selfReference {
TextToSpeech(
applicationContext,
{ self.setLanguage(Locale.UK) }
)
}
关于android - 匿名 Kotlin 监听器中未解析的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35049850/