我想知道:
背景:
我正在为Scala + Java设计嵌入式数据库作为辅助项目。虽然我希望它可以从Java中使用,但是我在Scala中编写它以获得额外的灵活性/功能,并且因为编写Java代码会使我的灵魂死亡。
我正在研究我想要的模型定义。我最初的想法是解析一些模型定义文件并生成Scala类。但是我认为现在我希望它们可以在Scala代码中定义,这样就不需要解析,人们可以充分利用Scala来定义和定制模型(例如自定义列类型)。&#39 ;我的Python / Django体验中的一个有价值的功能。
到目前为止,我有类似的内容:
@model
class Person {
val Name = StringColumn(length=32)
val BirthDate = DateColumn(optional=true)
}
@model
class Student extends Person {
val GPA = FloatColumn(propertyName="gpa")
}
@model
class Teacher extends Person {
val salary = NumericColumn()
}
哪会产生:
class Person {
val Name = StringColumn(name="name", length=32)
val BirthDate = DateColumn(name="birthDate", optional=true)
// generated accessor methods
def name = Person.Name.get(...)
def name_= (name : String) : Unit = Person.Name.set(..., name)
// etc ...
}
// static access to model metadata, e.g. Person.Name is an immutable StringColumn instance
object Person extends Person
class Student extends Person {
val GPA = DoubleColumn(name = "GPA")
def gpa = ...
def gpa_= (value : Float) = ...
}
object Student extends Student
class Teacher extends Person {
// You get the idea
}
object Teacher extends Teacher
在线查看一些示例并进行一些研究,似乎使用特殊的@model注释进行AST转换实际上可以生成所需的代码,可能需要一些帮助,例如:让用户定义对象以及模型定义。我是对的,这可以做到吗?
这个想法让我遇到了一些问题:
使用脚本生成代码更加适合IDE,但它很麻烦,可能需要更多工作,尤其是因为您必须保留自定义方法和事物。它还需要一个自定义构建步骤,您必须在更改模型时运行(这意味着您可能忘记执行此操作。)虽然IDE可能无法帮助您生成宏代码(但无论如何),编译器会对您大喊大叫如果你弄错了。这使我倾向于使用宏+注释。
你怎么看?我是Scala的新手,我有点怀疑我是如何定义模型并为它们生成实现的最佳方法。你会怎样做得更好?答案 0 :(得分:1)
可能是的。编写和调试宏可能会令人不愉快,但它们确实有效。
好像你已经有了解决方案
Scala IDE倾向于正确处理宏(我的意思是,他们必须,他们是语言的一部分,并在一些非常基础的库中使用),所以我不担心;如果有任何宏比外部代码步更加理想,因为宏将与用户的更改保持同步。
在使用宏之前,我会看看你是否可以在vanilla scala中实现你想要的东西。请记住,类似于类的东西不一定是实际的案例类;看看Shapeless generic records,了解如何从外部某处表示一个类型良好的“行”命名值。我认为一个能够将这些记录与SQL之间的结构映射到一起的系统最终可能比基于“特殊”案例类的系统更具原则性(即更易于推理)。