scala - 确定 Scala 类中 Option 字段的类型

标签 scala reflection

问题

如何确定类中每个字段的类型?

给定以下案例类别:

case class GenericCaseClass(
    a: Boolean,
    b: Byte,
    c: Short,
    d: Int,
    e: Long,
    f: Float,
    g: Double,
    h: Char,
    i: String,
    j: Option[Boolean],
    k: Option[Byte],
    l: Option[Short],
    m: Option[Int],
    n: Option[Long],
    o: Option[Float],
    p: Option[Double],
    q: Option[Char],
    r: Option[String]
)

初步尝试

import java.lang.reflect.{Field, ParameterizedType}

def printType(field: Field): Unit = {
    val scalaClass = field.getType

    if (scalaClass == classOf[Boolean]) {
        println("Boolean")
    } else if (scalaClass == classOf[Byte]) {
        println("Byte")
    }
    ...
    } else if (scalaClass == classOf[Option[Boolean]]) {
        println("Boolean")
    } else if (scalaClass == classOf[Option[Byte]]) {
        println("Byte")
    }
    ...
}

classOf[GenericCaseClass].getDeclaredFields.foreach(
    declaredField => {
        printType(declaredField)
    }
)

初步结果

  • bool 值
  • 字节
  • 简短
  • 整数
  • float
  • 查尔
  • 字符串
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]
  • 选项[ bool 值]

当前尝试

我将以下内容添加到 if 语句链的开头,以尝试获取选项的内部类型:

if (scalaClass == classOf[Option[_]]) {
    val innerType = field
        .getGenericType
        .asInstanceOf[ParameterizedType]
        .getActualTypeArguments
        .head
        .getTypeName

    println("Option[_] -> " + innerType)
}

但它似乎只适用于字符串:

  • bool 值
  • 字节
  • 简短
  • 整数
  • float
  • 查尔
  • 字符串
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.Object
  • 选项[_] -> java.lang.String

注意:我使用的是 Scala 版本 2.11.11。

最佳答案

使用 Java 反射很快就让我头疼了,所以这里有一个非常简单的 Scala 解决方案:

import scala.reflect.runtime.universe._

//--Your case class definition--//

val values = typeOf[GenericCaseClass].members.filterNot(_.isMethod)

def prettyPrintField(symbol: Symbol): Unit = {
  val name = symbol.name
  val typeSignature: Type = symbol.typeSignature
  println(s"$name: $typeSignature")
}

values.foreach(prettyPrintField)

输出:

r : Option[String]
q : Option[Char]
<- rest of fields ->
a : Boolean

关于scala - 确定 Scala 类中 Option 字段的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51485930/

相关文章:

c++ - 使用概念检查类型 T 是否具有字段 F

scala - FOR 循环多个生成器

scala - ZIO Fiber orElse 生成异常消息

scala - Spark中的split()函数有什么作用

Scala - 辅助构造函数总是必须调用另一个构造函数有什么好处?

java - 在 Java 中通过类型转换分配属性值

android - 从 Android 中的外部 native 可执行文件调用 java 代码

c# - PropertyInfo.GetValue() - 如何在 C# 中使用反射索引通用参数?

c# - 使用反射创建通用委托(delegate)

使用设置为 null 的隐式 val 时,Scala 编译器的行为不符合预期