【问题标题】:Dynamically generate case class in Scala在 Scala 中动态生成案例类
【发布时间】:2012-05-14 12:23:58
【问题描述】:

我想读取一个相当大的 csv 文件并对其进行处理(切片、切块、汇总等)interactively(数据探索)。我的想法是将文件读入数据库(H2)并使用SQL对其进行处理:

  1. 读取文件:我用Ostermiller csv parser

  2. 确定每一列的类型:我随机选择50行,导出每一列的类型(int、long、double、date、string)

  3. 我想用Squeryl来处理。为此,我需要动态创建一个案例类。这是目前为止的瓶颈!

  4. 我将文件上传到 H2 并使用任何 SQL 命令。

我的问题:

  • 在 Scala 中是否有更好的通用交互方式来执行此操作?
  • 有没有办法解决第三点?换一种说法,给定一个类型列表(对应于 csv 文件中的列),是否可以动态创建对应于 Squeryl 中的表的案例类?据我了解,我可以使用宏来做到这一点,但我没有足够的经验来做到这一点。

【问题讨论】:

  • 你有没有想过使用 Scala 以外的东西?喜欢Gnu R
  • @ziggystar 我在日常工作中广泛使用 R。它在 R 中绝对是可行的!我正在尝试探索 scala 进行数据分析...
  • 这是一个高度相关的问题,得到了好评:dynamically creating case classes with macros

标签: scala macros squeryl


【解决方案1】:

我认为您对第一个问题的处理方法听起来很合理。

关于您的第二个问题 - 作为 drexin 答案的补充 - 可以使用 ASM 等库生成字节码。使用这样的库,您可以生成与案例类相同的字节码。

【讨论】:

    【解决方案2】:

    由于 scala 是一种静态类型语言,除了反射之外没有其他方法可以动态创建类,反射是缓慢而危险的,因此应该避免。即使使用宏,您也无法做到这一点。宏在编译时评估,而不是在运行时评估,因此您需要在编译时了解数据的结构。如果您甚至不知道您的数据是什么样的,您需要案例类做什么?与使用 Map[String,Any] 相比,您期望从中获得什么好处?

    【讨论】:

    • 内存(文件可能非常大)、性能(?)、利用 SQL 知识等
    【解决方案3】:

    我认为您想创建一个密封的基类,然后创建一系列案例类作为它的子类。每个子类将包装您支持的不同类型。

    然后您可以使用匹配语句和解构来处理各个类型,并通过基类在无关紧要的地方对其进行通用处理。

    你不能为整行创建一个类,因为你在编译时对它的了解不够。即使您可以动态生成一个类(可能通过在运行时调用编译器),您也无法从类型安全中受益,而且您的大部分代码无论如何都必须对其进行通用处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      相关资源
      最近更新 更多