【问题标题】:assign any val scala pureconfig during configuration read在配置读取期间分配任何 val scala pureconfig
【发布时间】:2017-11-29 11:41:37
【问题描述】:

我知道这违背了 Scala pureconfig 的本质......但是...... 使用 scala pureconfig 配置读取这个案例类是否可行,以便构造函数参数“变量”不具有强类型值(作为字符串)具有 Any 类型或至少 String、Integer、Double、Array [字符串],数组[整数],数组[双]。

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

据我所知,CoProductHint 和 Custom Reader 方法都不起作用......

【问题讨论】:

    标签: scala types typesafe pureconfig


    【解决方案1】:

    默认情况下,pureconfig 不提供读取Any 的方法。如果您想阅读特定的类Any,那么您可以在该类的上下文中为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,[]))
    

    unwrappedConfigValue 递归转换为Any

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

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

    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 可以拥有的可能值,如果您正在做的事情有问题,让编译器帮助您。

    【讨论】:

    • @YordanGeorgiev,我怀疑除非您明确分配奖金,否则它可能不会自动分配,因为您在选择正确答案后开始发放奖金。
    【解决方案2】:

    您可以将该字段设为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))
    

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 2021-01-31
      • 2014-08-07
      • 1970-01-01
      • 2015-11-02
      • 2015-04-03
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      相关资源
      最近更新 更多