【发布时间】:2018-03-14 13:06:24
【问题描述】:
我正在尝试利用 Groovy 的 Operator Overloading,在 Groovy 上下文(GroovyShell)中对我的 Java 类使用方法:
我的类实际上是键和值的有序映射,所以界面看起来像这样:
public interface GroovyMap<K, V> {
// gets the value associated with the given key
V getAt(K key);
// gets the nth value, at the given index, in the ordered sequence of values
V getAt(int index);
}
getAt(K key) 方法在 Groovy 中运行良好:
GroovyMap<LocalDate, Double> map = ...
K key = ...
Double value = map[key];
但是,getAt(int index) 方法在 Groovy 中不工作 - 即:
GroovyMap<LocalDate, Double> map = ...
int i = 0;
Double value = map[i];
会抛出一个CastClassException:
java.lang.Integer 不能转换为 javax.time.calendar.LocalDate
我不完全确定这里发生了什么:
- Groovy 在数字和原语方面有一些奇怪的行为(例如,
0.0被有效地解释为new BigDecimal("0.0")),但我认为将i明确定义为int可以解决这个问题。李> - 看起来 Groovy 运算符重载正在装箱任何原始值,因此它试图将
Double传递给有效的getAt(LocalDate key)方法。但是,我找不到任何与此相关的文档。如果是这样的话,你能指导我去任何这样的地方吗? - 这里还有什么我不知道的事情吗?
【问题讨论】:
-
哪个 groovy 版本?您是否尝试过
@CompileStatic的调用代码?对我(2.5.0-beta-2)来说,这改变了行为,但对我来说,int 有效,而 Object 因 MissingPropertyException 而失败。除非我添加@CompileStatic来修复它。 -
是否有理由必须同时拥有这两种方法,称为
getAt? -
另外,这个 Listy 地图的用例是什么?我担心你会两全其美......我不记得需要一个也可索引的地图......我想你可以缓存索引来尝试提高查找速度?
-
@Mene - Groovy 2.4.7。调用代码是一个非常轻量级的脚本环境——即创建一个 GroovyScript,所以我不确定注释是否合适——即用户可以更轻松地编写
map.getAt(i)。 -
@tim_yates - 为什么两者都使用 getAt()?因为那是 Groovy 运算符重载契约。用例是什么?没关系,但是这个“listy map”是一个时间序列,所以它可以被迭代,或者通过索引或键查询,以及我们认为有用的各种其他功能。
标签: java groovy operator-overloading