2010-06-05 7 views
3

Je voudrais créer un type de carte donc quelque chose comme ci-dessous est possible:Comment créer un type de carte qui autorise plusieurs types de clés et de valeurs?

VariantMap(1) = "Test" 
VariantMap("a") = 42 

et VariantMap("a") aurait un type de Option[Int]. Voici le code que je suis à ce jour qui se traduit par Option[Nothing]:

object VariantMap { 
    import scala.reflect.Manifest 

    private var _map= Map.empty[Any,(Manifest[_], Any)] 

    def update[T](name: Any, item: T)(implicit m: Manifest[T]) { 
    _map = _map(name) = (m, item) 
    } 

    def apply[T](key:Any)(implicit m : Manifest[T]) = { 
    val o = _map.get(key) 

    o match { 
     case Some((om: Manifest[_], s : Any)) => Some[T](s.asInstanceOf[T]) 
     case _ => None 
    } 
    } 
} 

Je suis nouveau scala donc je présente mes excuses si je manque quelque chose évidente.

+0

Existe-t-il un modèle fixe de types clé/valeur? Ou avez-vous juste plusieurs types de clés et plusieurs types de valeur, l'un des premiers étant associé à l'un de ces derniers? Ou est-ce juste quelque chose à quoi que ce soit? Dans ce cas, utilisez simplement Map [Any, Any] et utilisez une correspondance comme cas de type sur les valeurs qui sortent. –

Répondre

2

Je ne sais pas s'il est directement possible de faire ce que vous voulez. La méthode apply prend un paramètre de type [T], mais si vous ne le spécifiez pas, le compilateur ne sait pas ce que le type T représente exactement. Dans ce cas, il infère Nothing, le sous-type de tout autre type.

Utilisation de votre code, fournissant un paramètre de type donne le résultat suivant:


scala> VariantMap[Int]("a") 
res0: Option[Int] = Some(1) 

scala> VariantMap[String]("a") 
res1: Option[String] = Some(1) 

Alors maintenant, tout type est ok, pas exactement soit parfait. Vous pouvez améliorer légèrement avec la variation suivante:


object VariantMap { 
    import scala.reflect.Manifest 

    private var _map= Map.empty[Any,(Manifest[_], Any)] 

    def update[T](name: Any, item: T)(implicit m: Manifest[T]) { 
     _map = _map(name) = (m, item) 
    } 

    def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = { 
    val o = _map.get(key)  
    o match { 
     case Some((om: Manifest[_], s : Any)) => if (om None 
    } 
    } 
} 

scala> VariantMap("a") 
res0: Option[Nothing] = None 

scala> VariantMap[Int]("a") 
res1: Option[Int] = Some(1) 

scala> VariantMap[String]("a") 
res2: Option[String] = None 

Ce qui est pas vraiment ce que vous avez probablement voulu (ce juste un type carte de sécurité), mais je ne vois vraiment pas une meilleure solution en ce moment .

Questions connexes