【问题标题】:Defining implicit format for Enumeration objects via trait in Scala通过 Scala 中的 trait 定义枚举对象的隐式格式
【发布时间】:2023-03-04 05:30:01
【问题描述】:

我试图为多个对象定义一个隐式特征,以便在反序列化枚举的 JSON 值时使用。我了解如何在对象中执行此操作,但我希望将此行为模板化以保持我的代码干燥。我可以通过执行以下操作来完成此操作:

object SomeEnum extends Enumeration {
  type SomeEnum = Value
  val FIRST: SomeEnum = Value("First")
  val SECOND: SomeEnum = Value("Second")
  implicit object SomeEnumFormat extends Format[SomeEnum] {
    def writes(o: SomeEnum): JsValue = JsString(o.toString)

    def reads(json: JsValue): JsResult[SomeEnum] = json match {
      case JsString(x) => JsSuccess(SomeEnum.withName(x.toLowerCase.capitalize))
      case _ => JsError()
    }
  }
}

以下是我一直在尝试的:

object SomeEnum extends Mappable {
  val FIRST: SomeEnum = Value("First")
  val SECOND: SomeEnum = Value("Second")
}

object SomeOtherEnum extends Mappable {
  val ABC: SomeOtherEnum = Value("Abc")
  val DEF: SomeOtherEnum = Value("Def")
}

trait Mappable extends Enumeration {
  implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)

  def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)

  implicit object someFormat extends Format[Class[_ <: Mappable]] {
    def writes(o: Class[_ <: Mappable]): JsValue = JsString(o.toString)

    def reads(json: JsValue): JsResult[Value] = json match {
      case JsString(x) => JsSuccess(this.asInstanceOf[Mappable].withName(x.toLowerCase.capitalize))
      case _ => JsError()
    }
  }
}

我希望继承的特征会以相同的方式为扩展特征的类提供隐式对象的模板版本,但我收到以下错误:

found   : Mappable#Value
required: Mappable.this.Value

如果我将 read 的返回类型设置为JsResult[Mappable#Value] 代码不会编译,因为没有找到指定枚举类型的隐式声明。任何帮助将不胜感激。

【问题讨论】:

    标签: scala object inheritance enums traits


    【解决方案1】:

    我最初误解了正在发生的事情,以下是有效的解决方案

    object SomeEnum extends Mappable {
      type SomeEnum = Value
      val FIRST: SomeEnum = Value("First")
      val SECOND: SomeEnum = Value("Second")
    }
    
    object SomeOtherEnum extends Mappable {
      type SomeOtherEnum = Value
      val ABC: SomeOtherEnum = Value("Abc")
      val DEF: SomeOtherEnum = Value("Def")
    }
    
    trait Mappable extends Enumeration {
      implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)
    
      def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)
    
      implicit object someFormat extends Format[Value] {
        def writes(o: Value): JsValue = JsString(o.toString)
    
        def reads(json: JsValue): JsResult[Value] = json match {
          case JsString(x) => JsSuccess(withName(x.toLowerCase.capitalize))
          case _ => JsError()
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-18
      • 2019-07-27
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 2011-11-17
      相关资源
      最近更新 更多