在Scala中动态生成案例类

时间:2012-05-14 12:23:58

标签: scala macros squeryl

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

  1. 阅读文件:我使用Ostermiller csv parser

  2. 确定每列的类型:我随机选择50行并派生每列的类型(int,long,double,date,string)

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

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

  5. 我的问题:

    • 在Scala中有更好的通用交互方式吗?
    • 有没有办法解决第3点?为了说明不同,给定一个类型列表(对应于csv文件中的列),是否可以动态创建一个与Squeryl中的表对应的案例类?根据我的理解,我可以使用宏来做到这一点,但我没有足够的曝光来做到这一点。

3 个答案:

答案 0 :(得分:3)

我认为你对第一个问题的看法听起来很合理。

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

答案 1 :(得分:2)

由于scala是一种静态类型语言,除了反射之外没有办法动态创建类,这种反应很慢而且很危险,因此应该避免。即使使用宏,也无法做到这一点。宏在编译时进行评估,而不是在运行时进行评估,因此您需要在编译时知道数据的结构。如果您甚至不知道您的数据是什么样的,那么您需要什么案例类?与使用Map[String,Any]相比,您对此有何期待?

答案 2 :(得分:1)

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

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

由于您在编译时对此知之甚少,因此无法为整行创建类。即使您可以动态生成一个类(可能通过在运行时调用编译器),您也无法从类型安全中受益,并且大多数代码都必须始终对其进行处理。