android - 匿名 Kotlin 监听器中未解析的引用

标签 android text-to-speech kotlin

我有下面的代码。它是 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 conversionOnInitListener 替换为 lambda。简而言之,但仍然可以在那里使用对象表达式。


UPD:检查this question我努力推广这种方法。使用它,你可以写

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

sources on Github .

关于android - 匿名 Kotlin 监听器中未解析的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35049850/

相关文章:

android - 如果已经在播放Y,如何定义播放Z的按钮?

Android JsonObject 解析带双引号的字符串

java - 空对象引用上的“android.content.res.Resources android.content.Context.getResources()”。将字符串数组转换为语音

Windows 8 语音转文本和文本转语音 API

android - 如何在带有 Koltllin 的 Android 应用程序中使用 Response.Listener Volley

android - 测试 RxJava 无限间隔

android - 如何在 Android 中设计此 UI?

android - Android 中 ToolBar 的 ActionbarActivity 替代方案

android - 对于非默认语言,在 2.1 中使用 TextToSpeech.Engine.ACTION_CHECK_TTS_DATA 的正确方法是什么?

android - JobScheduler JobService 在没有应用程序的情况下启动