斯卡拉反射 [英] scala reflection

查看:117
本文介绍了斯卡拉反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个散列表来存储参数名称及其值。然而,参数具有不同的类型。我可以使用HashMap [String,Any],但我不知道他们以后的类型。无论如何,我可以恢复类型信息吗?或者有什么更好的方法来存储pair?

解决方案

您是否想要访问静态类型信息或动态类型信息?如果你是在前者之后,你可以使用键入的键。这些行应该工作:

  final class Key [T] 

object Registry {
private var backingMap:Map [Key [_],_] = Map.empty
$ b $ def def [T](k:Key [T],v:T)= backingMap + =(k - > v)

def get [T](k:Key [T]):Option [T] = backingMap get k map(_.asInstanceOf [T])
}

scala> val strKey = new Key [String]
strKey:Key [String] = Key @ 31028a

scala> val intKey = new Key [Int]
intKey:Key [Int] = Key @ 7ae77ca4

scala> Registry.put(strKey,asdf)

scala> Registry.get(strKey)
res0:Option [String] =一些(asdf)

scala> Registry.put(intKey,asdf)
< console>:10:error:type mismatch;
found:Key [Int]
required:Key [Any]
Registry.put(intKey,asdf)

或者,您可以使用非类型化的键并将类型信息存储在使用清单的Map中(如 Daniel建议):

  class Registry [K] {
import scala.reflect.Manifest
$ b $ private var _map = Map。清空[K,(Manifest [_],Any)]

def put [T](key:K,item:T)(implicit m:Manifest [T]){
_map (key:K)(隐含的m:Manifest [T]):选项[T] = {
for((om,v)< - _map get key,如果om<:< m)
yield v.asInstanceOf [T]
}
}

后一种方法的优点是您可以使用任何东西作为关键字,而且您不必通过o严谨的键入对象周围。但是,它有一个缺点,即在调用 get 方法时必须指定值类型。如果指定了错误的类型,就会得到 None ,就好像该键完全不在注册表中一样,而使用键入的键可以保证关联任何值用钥匙。

I want to create a hashmap to store parameters names and their values. The parameters however are with different types. I could use HashMap[String, Any], but I wouldn't know which types they are later on. Is there anyway I can recovery the type information? Or is there any better way to store pair?

解决方案

Do you want access to the static type information, or the dynamic type information? If you're after the former, you can use typed keys. Something along these lines should work:

final class Key[T]

object Registry {
   private var backingMap: Map[Key[_], _] = Map.empty

   def put[T](k: Key[T], v: T) = backingMap += (k -> v)

   def get[T](k: Key[T]): Option[T] = backingMap get k map (_.asInstanceOf[T])
}

scala> val strKey = new Key[String] 
strKey: Key[String] = Key@31028a

scala> val intKey = new Key[Int]
intKey: Key[Int] = Key@7ae77ca4

scala> Registry.put(strKey, "asdf")

scala> Registry.get(strKey)
res0: Option[String] = Some(asdf)

scala> Registry.put(intKey, "asdf")
<console>:10: error: type mismatch;
 found   : Key[Int]
 required: Key[Any]
       Registry.put(intKey, "asdf")

Alternately, you can use untyped keys and store the type information in the Map using manifests (as Daniel suggested):

class Registry[K] {
   import scala.reflect.Manifest

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

   def put[T](key: K, item: T)(implicit m: Manifest[T]) {
      _map += (key -> (m, item))
   }

   def get[T](key:K)(implicit m : Manifest[T]): Option[T] = {
      for ((om, v) <- _map get key if om <:< m) 
         yield v.asInstanceOf[T]
   }
}

The latter approach has the advantage that you can use anything as a key, and you don't have to pass the original typed key objects around. However, it has the drawback that you must specify the value type when you call the get method. If you specify the wrong type you'll get None just as if the key is not in the Registry at all, whereas with typed keys you're guaranteed to get any value associated with a key.

这篇关于斯卡拉反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆