Хотите ли вы получить доступ к информации статического типа или информации динамического типа?Если вы после первого, вы можете использовать печатные ключи.Что-то вроде этого должно работать:
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")
В качестве альтернативы, вы можете использовать нетипизированные ключи и сохранять информацию о типе на карте, используя манифесты (как Даниил предложил ):
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]
}
}
Последний подход имеет то преимущество, что вы можете использовать что угодно в качестве ключа, и вам не нужно передавать исходные типизированные ключевые объекты.Однако у него есть недостаток: вы должны указывать тип значения при вызове метода get
.Если вы укажете неправильный тип, вы получите None
, как если бы ключ вообще не находился в реестре, тогда как с набранными ключами вы гарантированно получите любое значение, связанное с ключом.