我正在尝试制作自定义异构列表和地图.虽然有使用Manifest的例子,但是Scala 2.10它们已被弃用,我应该使用TypeTags(或Classtags).在地图的情况下,似乎我可以使用(比如)元组字符串 - >(TypeTag [_ <:Any],Any)保留Any与Type的绑定.
我的问题是如何从恢复的TypeTag和未定义的T中获取,以便能够返回TypeTag.tpe的实例 - 在我所拥有的代码中
//** How do I use saved typeTag to define T here?**
如上所述,方法get中没有编译器错误,但T设置为Nothing并返回Some(Nothing).我希望我的注释掉的行能够工作:
case Some( x ) => // println( "Get 2*'pi'=" + x*2 )有一个编译器消息,"value*不是Nothing的成员".我意识到我可以更紧凑地编写,但是完成之后,我可以在我的IDE中鼠标悬停并按照一步一步进行操作.有一个相关的问题 - Scala:什么是TypeTag以及如何使用它? 但它似乎没有走"最后一英里" - 重新选择任何一个.
这该怎么做?
这是我到目前为止的代码:
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
}
}
Run Code Online (Sandbox Code Playgroud)
T 是在调用 get 方法时定义的,不能在函数内将其更改为其他类型。编译器需要信息来获取 T 的类型信息,或者您必须显式提供它:
def get[T](key: String) = m.get(key).map(_.asInstanceOf[T])
get[Int]("anInt")
Run Code Online (Sandbox Code Playgroud)
如果键入一个键,则可以推断出 T:
class Key[T](name: String)
def get[T](key: Key[T]) = ...
get(Key[Int]("anInt"))
Run Code Online (Sandbox Code Playgroud)
要在从地图获取时检查类型是否正确,您可以执行最初所做的操作,保存类型和值:
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1198 次 |
| 最近记录: |