Groovy自动生成getter和setter,例如当我输入:
int someField
我得到了字段+ getter + setter。现在我想在setter上添加一个注释(例如来自GContracts的@ Requires / Ensures):
@Ensures({someField >= 0 && someField <= 100})
int someField
然后我得到错误:元素FIELD上不允许使用注释groovy.lang.GrUnit - GrUnit和GContracts仅识别方法上的注释。解决方法是明确编写getter:
@Requires({...})
void setSomeField(int newValue) { ... }
有更好的解决方案吗?在Scala中有一个优雅的解决方案:http://www.scala-lang.org/api/current/scala/annotation/target/package.html
Groovy中有类似的东西吗?或者:也许GContracts的一些解决方法允许这样的注释?
答案 0 :(得分:4)
Groovy编译器中有9个编译阶段。 getter和setter是在编译阶段很晚生成的,它们是在GContracts运行后生成的。
如果您想让代码看起来像生成的getter / setter被注释那么您必须自己生成getter / setter对并注释它们。具体来说,将两个新的FieldNode添加到ClassNode(只要它们尚不存在)。字段节点是AnnotatedNode,因此您可以添加所需的任何注释。只要你在 GContracts运行之前的阶段执行此操作,那么GContracts永远不会知道不同的。
那就是说,这听起来像是一个GContracts功能请求。
答案 1 :(得分:2)
正如您所指出的,GContracts不提供字段注释(当前版本:1.2.4)。它甚至不会在GContracts运行之前添加的合成(生成)方法上执行AST转换。
简而言之:一个简单的解决方法是添加自定义setter方法。
另一方面,如果你要使用@Invariant来保持一个类不变的类,它会预先为所有属性生成setter方法,以便在执行setter方法之前和之后检查类的不变量。
话虽这么说,考虑将@Requires和@Ensures纳入该过程可能是值得的 - 我创建了一个问题:http://gcontracts.lighthouseapp.com/projects/71511-gcontracts-core/tickets/32