2017-10-17 34 views
3

J'essaie d'implémenter un TypeAdapter GSON particulier en langage Kotlin pour mon projet Android.Implémentation de TypeAdapterFactory avec TypeAdapter dans Kotlin

Le problème que je suis confronté est erreur de compilation avec incapacité à déduire le type: Type inference failed: 'T' cannot capture 'in (T..T?'. Type parameter has an upper bound 'Enum<T>' that cannot be satisfied capturing 'in' projection

Le code est le suivant:

class SmartEnumTypeAdapterFactory(fallbackKey: String) : TypeAdapterFactory { 

    private val fallbackKey = fallbackKey.toLowerCase(Locale.US) 

    override fun <T : Any> create(gson: Gson?, type: TypeToken<T>): TypeAdapter<T>? { 
     val rawType = type.rawType 
     return if (!rawType.isEnum) null else SmartEnumTypeAdapter(rawType) 
    } 

    class SmartEnumTypeAdapter<T : Enum<T>>(classOfT: Class<T>) : TypeAdapter<T>() { 

     override fun write(out: JsonWriter?, value: T) { 
      TODO("not implemented") 
     } 

     override fun read(`in`: JsonReader?): T { 
      TODO("not implemented") 
     } 
    } 
    } 

La raison pour laquelle je veux avoir classOfT: Class<T> en tant que paramètre pour TypeAdapter est hors de contexte de ce problème.

+0

Ceci est un cas vraiment difficile ... Avez-vous essayé la mise en œuvre de cette chose en Java? Parce que vous pourriez alors vous convertir à Kotlin et voir si cela fonctionne, mais jusqu'ici je n'ai pas réussi à travailler dans les deux langues. – Robin

Répondre

0

Cela n'est pas possible car la méthode que vous écrasez (TypeFactory.create) n'a pas de limite supérieure (ce qui se traduit par <T : Any> dans Kotlin). Dans votre create méthode, T n'est pas garanti à Enum<T> (donc, il n'est pas possible de le passer en argument à votre adaptateur). Vous pouvez simplement supprimer la limite supérieure de votre classe d'adaptateur et la garder privée pour vous assurer que seule votre usine peut en créer des instances (et l'usine valide déjà si le type est une énumération).

class SmartEnumTypeAdapterFactory(fallbackKey: String) : TypeAdapterFactory { 

    private val fallbackKey = fallbackKey.toLowerCase(Locale.US) 

    override fun <T> create(gson: Gson?, type: TypeToken<T>): TypeAdapter<T>? { 
     val rawType = type.rawType 
     return if (!rawType.isEnum) null else SmartEnumTypeAdapter(rawType) 
    } 

    private class SmartEnumTypeAdapter<T>(classOfT: Class<in T>) : TypeAdapter<T>() { 

     override fun write(out: JsonWriter?, value: T) { 
      TODO("not implemented") 
     } 

     override fun read(`in`: JsonReader?): T { 
      TODO("not implemented") 
     } 
    } 
} 

(classOfT est un Class<in T> parce TypeToken.rawType() retourne un Class<? super T>)