2017-08-15 4 views
1

Dans le code ci-dessous, j'ai du mal à organiser correctement l'entrée/la sortie, de sorte que les deux opérations de() et() fonctionnent comme prévu. J'ai essayé de commuter in/out dans les propriétés et les paramètres de fonction, mais toujours avec des erreurs de frappe incorrectes.Comment faire l'inférence de type Kotlin à partir de la réflexion KClass?

class KStateMachine(private val states: List<StateHandler>) { 

var currentState: KClass<out StateHandler> 
    private set 
private val handlers:HashMap<KClass<in StateHandler>, Int> = HashMap() 

init { 
    currentState = states[0]::class 

    for (i in 0..states.size - 1) { 
     handlers.put(states[i]::class, i) 
    } 
} 

fun goto(toState: KClass<in StateHandler>) { 
    var index = handlers.get(toState) 
    if (index != null) { 
     var oldState = currentState 
     currentState = toState 
     states.get(index).from(oldState) 
    } else { 
     throw RuntimeException("to state unknown") 
    } 
} 

inline fun <reified T: StateHandler> goto() { 
    goto(T::class) 
} 

abstract class StateHandler { 
    abstract fun from(fromState: KClass<in StateHandler>) 
} 
} 

Répondre

1

Je suppose que vous n'avez pas besoin in -projections du tout pour les KClass es: votre code ne semble pas passer un StateHandler ou quelque chose avec paramétrés StateHandlerdans aux fonctions de KClass.

Si l'intention de la variance est que vous voulez que tous les KClass es pour représenter les sous-types de StateHandler, alors vous pourriez faire avec out -projections partout:

class KStateMachine(private val states: List<StateHandler>) { 

    private var currentState: KClass<out StateHandler> 
    private val handlers: HashMap<KClass<out StateHandler>, Int> = HashMap() 

    init { 
     currentState = states[0]::class 

     for (i in 0..states.size - 1) { 
      handlers.put(states[i]::class, i) 
     } 
    } 

    fun to(toState: KClass<out StateHandler>) { 
     var index = handlers.get(toState) 
     if (index != null) { 
      var oldState = currentState 
      currentState = toState 
      states.get(index).from(oldState) 
     } else { 
      throw RuntimeException("to state unknown") 
     } 
    } 

    abstract class StateHandler { 
     abstract fun from(fromState: KClass<out StateHandler>) 
    } 
} 
+0

Tout ce que je avais besoin, merci! – Martin