2016-01-27 17 views
5

Ho il seguente codice. È Kotlin. Qualche idea del perché textToSpeech da textToSpeech.setLanguage(Locale.UK) sta dicendo che non è stato risolto alcun riferimento per textToSpeech?Riferimento non risolto all'interno dell'ascoltatore di Kotlin anonimo

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

      }) 

In un primo momento ho pensato che è un'idea Kotlin plugin di bug, ma sembra che in realtà non può essere compilato

risposta

7

Kotlin ha indurito la politica variabili di inizializzazione, e ora è proibito fare riferimento alla variabile all'interno del suo inizializzatore, anche nelle espressioni lambda e oggetto, che sembra ragionevole: immagina che un lambda venga chiamato immediatamente prima dell'assegnazione della variabile.

Per il vostro caso, posso suggerire come soluzione alternativa utilizzando un object expression in questo costrutto abbastanza ingombrante:

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

Ciò inizializzare un oggetto anonimo con inner all'interno che sia accettabile attraverso value proprietà. Si noti che l'inizializzatore inner utilizza la proprietà value. Quindi lo value viene estratto e può essere utilizzato.

Ma si prega di tenere a mente che questo trucco non è sicura: in fase di esecuzione, utilizzando value prima inner è assegnato (ad esempio in TextToSpeech costruttore) getterà NullPointerException.

Inoltre, ho sostituito lo OnInitListener con un lambda utilizzando SAM conversion per essere breve, ma l'espressione dell'oggetto può ancora essere utilizzata lì.


UPD: controllo this question per il mio impegno a generalizzare questo approccio. Usandolo, è possibile scrivere

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

Vedere sources on Github.

Problemi correlati