是否可以在Scala中获取泛型类的类型名称?我知道在类型擦除的Java中这是不可能的,但我希望Scala是一个不同的情况.
目前我必须做类似的事情:
trait Model
case class User(id: String) extends Model
def fromMap[M<:Model : Manifest](data: Map[String, String], modelType: String) = {
modelType match {
case "user" => User(data.get("id").get)
}
}
val user = fromMap[User](Map("id" -> "id1"), "user")
Run Code Online (Sandbox Code Playgroud)
显然,如果我可以在不必将其传入的情况下解决"用户"问题会更容易.
可以从Manifest(或ClassManifest)中检索类名称manifest.erasure.getName(擦除是Class实例).例如
def className[A : ClassManifest] = classManifest[A].erasure.getName
Run Code Online (Sandbox Code Playgroud)
编辑:看过Derek的回答,这使得erasure.getName这个东西看起来相当愚蠢.我不考虑toString.我仍然希望以下内容可能会引起关注
使用ClassManifest和之间的区别在于Manifest,Manifest对于泛型类,类型参数保证可用,而它们是最好的努力ClassManifest(比较typeParameters两个类中的签名).这种保证的缺点是Manifest可能无法隐含地使用a ClassManifest.
您是否考虑过使用类型类?
trait BuilderFromMap[A] {def build(data: Map[String, String]): A}
// or better, return Option[A], accounting for possible failure
object User {
implicit val Builder extends BuilderFromMap[User] {...}
}
def fromMap[A](data: Map[String, String])(implicit builder: BuilderFromMap[A])
= builder.build(data)
Run Code Online (Sandbox Code Playgroud)
这样,fromMap只有当a Builder可用于此特定类时,调用才会编译,而不是使用a失败MatchError.
对于那些从 Scala 2.12.x 或 2.13.x 的世界来到这个问题的人来说,这ClassTag[T]是执行此操作的首选方法。
import scala.reflect._
trait Model
case class User(id: String) extends Model
def fromMap[M <: Model : ClassTag](data: Map[String, String]) = {
val modelType = implicitly[ClassTag[M]].runtimeClass.getSimpleName
modelType match {
case "User" => User(data("id"))
}
}
val user = fromMap[User](Map("id" -> "id1"))
Run Code Online (Sandbox Code Playgroud)
对于 Scala 2.11,以下代码有效:
import scala.reflect.runtime.universe.{typeOf, TypeTag}
def name[T: TypeTag] = typeOf[T].typeSymbol.name.toString
def fullName[T: TypeTag] = typeOf[T].typeSymbol.fullName
Run Code Online (Sandbox Code Playgroud)
执行示例:
scala> name[String]
res5: String = String
scala> fullName[String]
res6: String = java.lang.String
Run Code Online (Sandbox Code Playgroud)
参考: http: //www.scala-lang.org/api/2.11.0/scala-reflect/index.html
| 归档时间: |
|
| 查看次数: |
6488 次 |
| 最近记录: |