Groovy 似乎绕过了 Java 中的 a compilation error:
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
3 errors
groovy 编译器并没有抱怨,而是将需要前向声明的枚举值初始化为null:
public enum Direction {
North(South), South(North), East(West), West(East), Up(Down), Down(Up)
Direction(Direction d){
println "opposite of $this is $d"
}
}
Direction.South // Force enum instantiation in GroovyConsole.
Outputs:
opposite of North is null
opposite of South is North
opposite of East is null
opposite of West is East
opposite of Up is null
opposite of Down is Up
在 Java 中似乎工作得很好的一个解决方案是 adding a static block on the Direction class 来初始化 opposite 值。翻译成 Groovy 的话,就是:
enum Direction {
North, South, East, West, Up, Down
private Direction opposite
Direction getOpposite() { opposite }
static {
def opposites = { d1, d2 -> d1.opposite = d2; d2.opposite = d1 }
opposites(North, South)
opposites(East, West)
opposites(Up, Down)
}
}
Direction.values().each {
println "opposite of $it is $it.opposite"
}
现在prints the correct values:
opposite of North is South
opposite of South is North
opposite of East is West
opposite of West is East
opposite of Up is Down
opposite of Down is Up
更新
Another,也许更直接,解决方案可以使用枚举上的方向索引来找到相反的:
public enum Direction {
North(1), South(0), East(3), West(2), Up(5), Down(4)
private oppositeIndex
Direction getOpposite() {
values()[oppositeIndex]
}
Direction(oppositeIndex) {
this.oppositeIndex = oppositeIndex
}
}
但我发现第一个更清晰,因为它不需要那些神奇的索引数字呵呵。
更新 2
现在,我可能对这里的高尔夫球场有所了解,但你可以得到相反的方向without the need of an extra field,只需使用枚举值'ordinal()(它们的索引):
enum Direction {
North, South, East, West, Up, Down
Direction getOpposite() {
values()[ordinal() + ordinal() % 2 * -2 + 1]
}
}
它并不像看起来那么可怕!偶数方向(北、东、上)返回ordinal() + 1 的方向作为它们的相反方向,而奇数方向(其他方向)返回ordinal() - 1 的方向。当然它在很大程度上依赖于枚举中元素的顺序,但是,你不喜欢简洁吗? =D