I am trying to make custom heterogeneous lists and maps. Although there are examples around using Manifest, with Scala 2.10 they are deprecated and I should use TypeTags (or Classtags). In the case of maps it seems I can preserve the binding of an Any to a Type using (say) a tuple String->(TypeTag[ _ <: Any ], Any ).
My problem is how to get from the recovered TypeTag and an undefined T, to be able to return an instance of TypeTag.tpe - at the point in the code where I have
    //** How do I use saved typeTag to define T here?** 
As written, there are no compiler errors in method get, but T is set to Nothing and returns Some(Nothing). I would like my commented-out line to work:
      case Some( x ) => // println( "Get 2*'pi'=" + x*2 ) where there is a complier message, "value * is not a member of Nothing".
I realise I could write more compactly, but as done, I can mouse-over in my IDE and follow step by step.  There is a related question - Scala: What is a TypeTag and how do I use it?  but it does not seem to go the 'last mile' - retagging an Any.
How to do this?
Here is the code I have so far:
import scala.reflect._
import scala.reflect.runtime.universe._
import collection.mutable.Map
object Test extends HMap {
  def main( args: Array[ String ] ) {
    var hmap = new HMap
    hmap( "anInt" ) = 1
    hmap( "pi" ) = 3.1416f
    hmap( "c" ) = "hello"
    // Test
    val result = hmap.get( "pi" )
    result match {
      case Some( x ) =>
        println( "Get 'pi'=" + x*2 )
      case _ =>
    }
  }
}
class HMap {
  private var coreMap = 
    Map.empty[ String, ( TypeTag[ _ <: Any ], Any ) ]
  // Save the type tag with the value
  def update[ T: TypeTag ]( key: String, value: T ) = 
    coreMap.put( key, ( typeTag[ T ], value ) )
  override def toString = coreMap.toString
  def get[ T: TypeTag ]( key: String ): Option[ T ] = {
    val option = coreMap.get( key )
    val result = option match {
      case None => None
      case Some( x ) => {
        val typeTag = x._1; val value = x._2
        println( "Matched Type = " + 
            typeTag.tpe + "   Value=" + value )
        // **** How do I use saved typeTag to define T here? ****
        val v = value.asInstanceOf[ T ]
        val s = Some( v )
        println( "Returning " + s )
        s
      }
    }
    result
  }
}
Here is my own answer:
I don't need TypeTags and I don't really need a keyed type or a tuple. Just simple generics seems to do. I don't need a match & case classes enumerating the possible values for Any. Just a simple map of name-value pairs. I then access it using
    hmap.get Float  .... println( "Get 'pi'=" + x * 2 )
It seems reasonable and very readable to just invoke: hmap.get Float . The types are not checked at compile time and so I will get runtime errors if I ask for the wrong type. If I do decide to filter the types there is a place to do it. I should check for castability and let Option return None if it can't be done and not Exception as it does now.
To me the above is neater & reads nicer than casting later since all the error handling can be in the get rather than using :
    hmap.get("pi").asInstanceOf[Float]. 
Thanks for your help!
Here is the simpler code now:
 import collection.mutable.Map
object Test extends HMap {
  def main( args: Array[ String ] ) {
    var hmap = new HMap
    hmap( "anInt" ) = 1
    hmap( "pi" ) = 3.1416f
    hmap( "c" ) = "hello"
    // Test
    val result = hmap.get[ Float]( "pi" )
    result match {
      case Some( x ) =>
        println( "Get 'pi'=" + x * 2 )
      case _ => println("Not found")
    }
  }
}
class HMap {
  private var coreMap =
    Map.empty[ String, Any ]
  // Save the key with the value
  def update[ T ]( key: String, value: T ) =
    coreMap.put( key, value )
  def get[ T ]( key: String ): Option[ T ] = {
    val option = coreMap.get( key )
    option match {
      case None      => None
      case Some( x ) => Some( x.asInstanceOf[ T ] )
    }
  }
}
T is defined when you call the method get, you cant change it inside a function to another type. Compiler need information to get type information for T or you have to provide it explicitly:
def get[T](key: String) = m.get(key).map(_.asInstanceOf[T])
get[Int]("anInt")
If a key is typed, then T can be inferred:
class Key[T](name: String)
def get[T](key: Key[T]) = ...
get(Key[Int]("anInt"))
To check the type is correct when getting from map you can do what you did originally, save a type and a value:
val m = Map.empty[String, (Type, Any)]
def put[T: TypeTag](key: String, value: T) = m.put(key, (typeOf[T], value))
def get[T: TypeTag](key: String) = m.get(key) match {
    case Some((t, v)) if t =:= typeOf[T] => Some(v.asInstanceOf[T])
    case _ => None
}
来源:https://stackoverflow.com/questions/13165493/how-save-a-typetag-and-then-use-it-later-to-reattach-the-type-to-an-any-scala-2