在配置读取期间分配任何 val scala pureconfig

assign any val scala pureconfig during configuration read

我知道这违背了 Scala pureconfig 的本质……但是…… 对于这种情况 class,使用 scala pureconfig 配置读取来实现是否可行,这样构造函数参数 "variable" 的强类型值(作为字符串)就可以具有任何类型或至少具有字符串,整数、双精度、数组 [字符串]、数组 [整数]、数组 [双精度]。

  case class Filter(
  field: String,
  operator: String,
  variable: String  // should support Int , Double , List[String], List[Int]
  )

据我所知,CoProductHint 和自定义 Reader 方法都行不通......

您可以使该字段 ANY: 示例:

scala>   case class Filter(
     |   field: String,
     |   operator: String,
     |   variable: Any  // should support Int , Double , List[String], List[Int]
     |   )
defined class Filter

scala> Filter("anurag","data",List(12,34))
res5: Filter = Filter(anurag,data,List(12, 34))

scala> Filter("anurag","data",List(12.12,34.12))
res6: Filter = Filter(anurag,data,List(12.12, 34.12))

scala> Filter("anurag","data",List("Hello","Hii"))
res8: Filter = Filter(anurag,data,List(Hello, Hii))

默认情况下,pureconfig 不提供读取 Any 的方法。如果对于特定的 class 你想阅读 Any 那么你可以在 class:

的上下文中为 Any 定义一个编解码器
case class Filter(field: String, operator: String, variable: Any)

implicit val readFilter = {
  implicit val readAny = new ConfigReader[Any] {
    def from(config: ConfigValue): Either[ConfigReaderFailures, Any] = {
      Right(config.unwrapped())
    }
  }
  ConfigReader[Filter]
}

然后你可以阅读Filter

val config = ConfigFactory.parseString(
    """
    {
      field: "foo"
      operator: "bar"
      variable: []
    }
    """)
println(pureconfig.loadConfig[Filter](config))
// will print Right(Filter(foo,bar,[]))

unwrapped 递归地将 ConfigValue 转换为 Any

所以答案是肯定的,如果可能的话告诉 pureconfig 如何读取 Any

pureconfig默认不提供Any的编解码器的原因是因为Any是Scala中所有classes的祖先,不可能创建一个任何东西的编解码器(例如数据库连接)。当您知道您需要一组受限制的类型时,例如您列出的类型,您可以将所有内容包装在一个联积中:

sealed abstract class MySupportedType
final case class MyInt(value: Int) extends MySupportedType
final case class MyDouble(value: Double) extends MySupportedType
final case class MyListOfString(value: List[String]) extends MySupportedType
final case class MyListOfInt(value: List[Int]) extends MySupportedType

final case class Filter2(field: String, operator: String, variable: MySupportedType)

然后使用默认方式提取副产品值或自定义编解码器 MySupportedType

val config = ConfigFactory.parseString(
    """
    {
      field: "foo"
      operator: "bar"
      variable: {
        type: mylistofint
        value: []
      }
    }
    """)
  println(pureconfig.loadConfig[Filter2](config))
  // will print Right(Filter2(foo,bar,MyListOfInt(List())))

使用余积而不是 Any 限制了 variable 可能具有的值,如果您正在做的事情有问题,让编译器帮助您。