匿名Kotlin监听器中未解决的引用

我有下面的代码。 这是Kotlin。 任何想法为什么来自textToSpeech.setLanguage(Locale.UK)说是没有解决textToSpeech参考?

 val textToSpeech = TextToSpeech( applicationContext, object : TextToSpeech.OnInitListener { override fun onInit(status: Int) { if (status == TextToSpeech.SUCCESS) { textToSpeech.setLanguage(Locale.UK) } } }) 

起初我认为这是一个想法kotlin插件的错误,但它似乎实际上不能被编译

Kotlin加强了变量的初始化策略,现在禁止在其初始化器中引用变量,即使在lambda表达式和对象表达式中,这似乎是合理的:想象一下lambda在变量赋值之前立即被调用。

对于你的情况,我可以建议在这个相当麻烦的构造中使用对象表达式作为解决方法:

 val textToSpeech = object { val value: TextToSpeech get() = inner private val inner = TextToSpeech( applicationContext, { value.setLanguage(Locale.UK) } ) }.value 

这将初始化一个匿名对象与里面内部是通过value属性可以接受的。 请注意, inner初始化器使用value属性。 然后,该value被提取并可以使用。

但是请记住,这个技巧是不安全的:在运行时,在赋值之前使用value (例如在TextToSpeech构造函数中)会抛出NullPointerException

另外,我使用SAM转换将lambda表达式的OnInitListener替换为short,但仍然可以在那里使用对象表达式。


UPD:检查这个问题是为了推广这个方法。 使用它,你可以写

 val textToSpeech = selfReference { TextToSpeech( applicationContext, { self.setLanguage(Locale.UK) } ) } 

查看Github上的资源 。