在Scala中,已声明字段的值获取转换为它的类声明的类型(In Scala, fetched val

2019-10-19 05:00发布

我想问一下如何实现在斯卡拉以下。 考虑

scala> case class C(i:Int)
defined class C

scala> val c = C(1)
c: C = C(1)

鉴于关注的一个领域,在这种情况下,

scala> val fname = "i"
fname: String = i

我们想找回我场在c中的原始值和类型。

第一,天真,尝试包括以下内容,

scala> val f = c.getClass.getDeclaredField(fname)
f: java.lang.reflect.Field = private final int C.i

scala> f.setAccessible(true)

scala> f.getType
res3: Class[_] = int

然而,

scala> val a:Int = f.get(c)
<console>:11: error: type mismatch;
 found   : Object
 required: Int
       val a:Int = f.get(c)
                        ^

换句话说,如何在C为我取的int值(*)

scala> :type -v case class C(i:Int)
// Type signature
AnyRef
        with Product
        with Serializable {
  val i: Int  <----------------------- (*)
  private[this] val i: Int
  def <init>(i: Int): C
  def copy(i: Int): C
...

并且不一定是int类型,考虑d J区域,

scala> case class C(i:Int)
defined class C

scala> case class D(j:C)
defined class D

scala> :type -v case class D(j:C)
// Type signature
AnyRef
        with Product
        with Serializable {
  val j: C
  private[this] val j: C
  def <init>(j: C): D
  def copy(j: C): D
...

非常感谢...

综上所述

特定

scala> f.get(c)
res1: Object = 1

scala> f.getType
res3: Class[_] = int

如何获得

val a = 1

其中,a是int类型的,并且知道仅从f.getType类型。

Answer 1:

静态类型f.get(c)Object ,因为它可以是任何类和任何领域。 然而,在运行时,它会返回一个Integer (用于Java包装类Int )。 您可以使用它转换

f.get(c).asInstanceOf[Int]

要么

f.getInt(c)

如果你事先知道您所要求的Int场。 如果不这样做,你可以模式匹配:

f.get(c) match {
  case i: Integer => ...
  case l: java.lang.Long => ...
  case s: String => ...
  // etc.
}

// actually compiles to same code, but avoids the need to use boxed classes
(f.get(c): Any) match {
  case i: Int => ...
  case l: Long => ...
  case s: String => ...
  // etc.
}

需要注意的是采取的分支依赖于该领域的实际价值,而不是其类型; 例如用于val f: Any = ""case s: String分支将被采用。

或者你可以使用f.getType得到它的类型,让你的逻辑取决于这一点。



文章来源: In Scala, fetched value of declared field cast to its class-declared type