2015-10-15 20 views
5

ho lezioneCome controllare il tipo generico in Kotlin?

class Generic<T : SuperType>() 

e questo codice is't corretto

fun typeCheck(s: SuperType): Unit { 
      when(s){ 
       is T -> //do some thin 
      } 
     } 

ma gettata s digitare Ts as T Mostra avviso - getto pericoloso.
Come verificare che s sia il tipo T?

+0

La stringa è definitiva, perché dovresti usare 'T: String'? –

+0

@cypressious è solo un esempio – andreich

risposta

5

I tipi generici non vengono reificati sulla JVM in fase di esecuzione, quindi non c'è modo di farlo in Kotlin. L'avviso è corretto perché il compilatore non può generare alcuna istruzione che fallirà quando il cast è terminato, quindi il cast è deselezionato, il che significa che il programma potrebbe, in un momento successivo, rompere o meno.

Una funzione correlata che potrebbe essere utile è reified type parameters in funzioni inline. Le classi non possono avere parametri di tipo reificato, quindi, se approfondisci un po 'di più sul tuo caso d'uso, posso provare ad aiutarti a ottenere ciò di cui hai bisogno.

13

Se è necessario verificare se qualcosa è di tipo generico T è necessario disporre di un'istanza di Class<T> da verificare. Questa è una tecnica comune in Java hwoever in Kotlin, possiamo usare un metodo di factory inline che ci fa diventare oggetto di classe.

class Generic<T : Any>(val klass: Class<T>) { 
    companion object { 
     inline operator fun <reified T : Any>invoke() = Generic(T::class.java) 
    } 

    fun checkType(t: Any) { 
     when { 
      klass.isAssignableFrom(t.javaClass) -> println("Correct type") 
      else -> println("Wrong type") 
     } 

    } 
} 

fun main(vararg args: String) { 
    Generic<String>().checkType("foo") 
    Generic<String>().checkType(1) 
} 
+0

Puoi rispondere per la mia domanda? https://stackoverflow.com/questions/47418161/kotlin-get-type-of-generic-class-without-instance – murt

+0

ottimo trucco! sai come farlo funzionare quando la classe 'Generic' è astratta? Il problema che sto riscontrando è la creazione di istanze dell'oggetto figlio sull'operatore 'invoke'. – ESala

+0

Non funzionerà così facilmente. Il costruttore della classe child dovrà passare l'istanza 'Class' al super costruttore. –

Problemi correlati