Неразрешенный справочник внутри анонимного слушателя Kotlin

У меня есть код ниже. Это Котлин. Любая идея, почему textToSpeech из 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) } } }) 

Сначала я предположил, что это ошибка плагина Idea kotlin, но кажется, что она на самом деле не может быть скомпилирована

    Kotlin упрочило политику инициализации переменных, и теперь запрещается ссылаться на переменную внутри ее инициализатора, даже в выражениях lambdas и object, что представляется разумным: представьте, что лямбда вызывается непосредственно перед назначением переменной.

    Для вашего случая я могу предложить в качестве обходного пути использование выражения объекта в этой довольно громоздкой конструкции:

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

    Это приведет к инициализации анонимного объекта с inner частью, которая приемлема с помощью свойства value . Обратите внимание, что inner инициализатор использует свойство value . Затем value извлекается и может использоваться.

    Но имейте в виду, что этот трюк небезопасен: во время выполнения, используя value перед назначением inner (например, в конструкторе TextToSpeech ), будет выбрасываться TextToSpeech NullPointerException .

    Кроме того, я заменил OnInitListener используя преобразование SAM, чтобы быть коротким, но выражение объекта все еще можно использовать там.


    UPD: проверьте этот вопрос для моих усилий по обобщению этого подхода. Используя его, вы можете написать

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

    См. Источники в Github .