【问题标题】:Is any chance to create new instanceable class or type from N mixed case classes?是否有机会从 N 个混合案例类中创建新的可实例类或类型?
【发布时间】:2018-08-09 17:15:20
【问题描述】:

假设我有如下案例类:

case class Id(id: Long)
case class Department(number: Long)
case class Employee(name: String, surname: String)

现在我想将这些类合并到一个新的类中,并在不编写另一个类的情况下创建该类型的实例:

type UberEmployee = Employee with Department with Id
val uberEmployeeInstance = new UberEmployee("Jon", "Smith", 1200, 1) 

val uberEmployeeInstance = MagicFactory[UberEmployee]("Jon", "Smith", 1200, 1)

是否有可能通过元编程或反射在 Scala 中实现这一目标?在我的想象中,使用 mixins 的类组合对我不起作用。

【问题讨论】:

    标签: scala reflection metaprogramming


    【解决方案1】:

    继承并不能真正做到,因为只有特征支持多重继承,所以你能做的最好的就是自动生成的转换方法。我假设您可以通过反射或某种代码生成来做到这一点。但可能最简单的方法是使用shapeless。事实上,这是直接来自 shapeless guide(第 75 页)的示例:

    import shapeless._
    import shapeless.ops.hlist._
    
    trait Migration[A, B] {
      def apply(a: A): B
    }
    
    implicit class MigrationOps[A](a: A) {
      def migrateTo[B](implicit migration: Migration[A, B]): B = migration(a)
    }
    
    implicit def genericMigration[A, B, ARepr <: HList, BRepr <: HList](
      implicit aGen: LabelledGeneric.Aux[A, ARepr], bGen: LabelledGeneric.Aux[B, BRepr],
      inter: Intersection.Aux[ARepr, BRepr, BRepr]): Migration[A, B] = new Migration[A, B] {
      def apply(a: A): B = bGen.from(inter(aGen.to(a)))
    }
    

    然后只需使用所有相关字段定义您的“uber”类并调用.migrateTo

    case class UberEmployee(id: Long, number: Long, name: String, surname: String)
    
    UberEmployee(123, 456, "John", "Doe").migrateTo[Employee]  // returns Employee("John", "Doe")
    

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 2022-08-10
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多