在编译时初始化工厂

时间:2018-03-25 11:53:20

标签: scala reflection compilation factory scala-meta

我有一个应该根据名称返回实现的工厂。

class Animal(Base):
    __tablename__ = 'animal'
    name = Column(String(16), primary_key=True)
    location = Column(Integer, ForeignKey(Dwelling.id))

为了每次调用" getModule"方法不创建实例,有一个映射,其中所有模块必须在bootstrap类中初始化。 我想摆脱手动执行此操作的需要(所有类都有一个独特的功能)。

我想到的选项列表:

  • 反思(我们可以使用Scala Reflection API或任何第三方) 图书馆)
    • 自动流程。
    • 需要在启动时立即初始化。
    • 反思很痛苦。
  • 元编程(ScalaMeta)+反射
    • 宏只会更改代码,执行会稍后执行。

我们可以将初始化过程移到编译时吗?

我知道编译器可以在编译之前优化和替换代码,下一个片段

    val moduleMap = Map(Modules.moduleName -> new ModuleImpl)
    def getModule(moduleName: String): Module =
        moduleMap.get(moduleName) match {
          case Some(m) => m
          case _ =>
            throw new ModuleNotFoundException(
              s"$moduleName - Module could not be found.")
        }

编译后编译器将该块更改为10,我们是否可以使用某些指令或其他工具在编译时评估和执行某些代码并仅使用最终值?

1 个答案:

答案 0 :(得分:0)

您使用任何框架还是自己编写?我回答了关于Guice here的类似问题。您也可以在没有Guice的情况下使用它:代替Module,您将需要从某处初始化您的工厂,并且在初始化期间,您将使用反射填充地图

总的来说,我认为这是最简单的方法。或者,您可以编写宏,它只是替换部分反射初始化,但不确定它会给您一些利润(如果我理解您的问题,这个初始化只会在启动时发生一次)。

我不知道scalameta如何帮助你?可能只有在您可以使用源树中的所有实现的情况下,您可以分析它并生成初始化(类似于宏)?可能会增加这样的优点,因为它更容易搜索实现,但会添加减号:仅适用于源代码中的实现。

您的编译时优化示例不适用。在您的示例中,您谈论编译时常量(即使算术可能有问题,请参阅this注释),但在您的问题中,您需要特定的运行时行为。所以compile time可能只是从我的角度来源代码生成代码或基于scalameta。