简体   繁体   English

Scala如何为地图编写get(name:String,type:Class)

[英]Scala How to write a get(name:String, type:Class) for map

I want to be able to have a map implementation of type [String,Any] in which i can store objects of different classes then i want to be able to do 我希望能够有一个[String,Any]类型的地图实现,其中我可以存储不同类的对象,然后我希望能够

import app.User;
....
usr = map.getAs("user",User)// with usr being an object of Class/Object User. If user is not of that type it throws an exception.

where user was previously stored in the map. 用户先前存储在地图中的位置。

Is this possible? 这可能吗?

I can even be a standalone method eg 我什至可以成为一个独立的方法,例如

 usr = getAs(map,"user",User)

Thanks 谢谢

You can use ClassTag . 您可以使用ClassTag I don't have a lot of experience with it, but something like that should work: 我没有很多经验,但是类似的事情应该起作用:

def getAs[T: ClassTag](m: Map[String, Any], key: String): T = 
  m(key).asInstanceOf[T]

Usage: 用法:

val map = Map[String, Any]("one" -> 1, "hello"-> "world")
getAs[String](map, "hello")
res1: String = world

I let you deal with the exception, you can simply wrap the asInstanceOf in a Try , or whichever strategy you prefer. 我让您处理异常,您可以将asInstanceOf简单地包装在Try ,或者使用您喜欢的任何策略。 I also recommend changing the return type to Option[T] . 我还建议将返回类型更改为Option[T]

Thanks vptheron. 谢谢vptheron。 That definitely works. 那绝对有效。 I took your advice and did it using Option[T] and used matching instead. 我接受了您的建议,并使用Option [T]进行了处理,而是使用了匹配。

def getAsOption[T: ClassTag](m: Map[String, Any], key: String): Option[T] =
m.get(key) match {
    case x : Option[T] => x
    case _ => None
}   

I wanted a mechanism to pass random stuff in the play framework and this looks like a good solution for me though the purists wont like it. 我想要一种在游戏框架中传递随机内容的机制,尽管纯粹主义者不喜欢这种机制,但这对我来说似乎是一个很好的解决方案。

I think using TypeTag will do better job unless you will never cast the values into generic types. 我认为使用TypeTag会做得更好,除非您永远不会将值转换为泛型类型。

import scala.reflect.runtime.universe._

trait Typed[A] {
  val value: A
  implicit val ttag: TypeTag[A]
}

def cast[A, B: TypeTag](v: Typed[A]): Option[B] = {
  val tA = typeOf[A](v.ttag)
  val tB = typeOf[B]
  def vB = v.value.asInstanceOf[B]
  if (tA <:< tB) Some(vB) else None
}

def getTyped[A, B, C: TypeTag](map: Map[A, Typed[B]], key: A): Option[C] = {
  map get key flatMap cast[B, C]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM