加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy compareTo for CustomClass和数字/字符串

发布时间:2020-12-14 16:21:48 所属栏目:大数据 来源:网络整理
导读:我正在构建DSL并尝试定义一个可以在表达式中使用的自定义类CustomClass def result = customInstance = 100 ? 'a' : 'b'if (customInstance == 'hello') {...} 当您的类定义了equals并同时实现Comparable(定义compareTo)时,Groovy不会调用==. 相反,Groovy调
我正在构建DSL并尝试定义一个可以在表达式中使用的自定义类CustomClass

def result = customInstance >= 100 ? 'a' : 'b'
if (customInstance == 'hello') {...}

当您的类定义了equals并同时实现Comparable(定义compareTo)时,Groovy不会调用==.

相反,Groovy调用具有分支逻辑的compareToWithEqualityCheck.除非您的自定义DSL类可以从String或Number分配,否则上面的示例将不会调用自定义compareTo.

您无法使用String扩展CustomClass.
我觉得我错过了什么.希望你能帮我弄清楚如何实现一个像我上面所示的简单案例.

解决方法

以下是一个简短的回答:您可以为CustomClass扩展GString.然后在两种情况下都会调用它的compareTo方法 – 当你检查相等性和实际比较时.

编辑:考虑以下情况,它将适用于1和2,但不适用于3.

customInstance >= 100      // case 1
customInstance == 'hallo'  // case 2
customInstance == 10       // case 3

现在我将解释我从Groovy的ScriptBytecodeAdapter和DefaultTypeTransformation中的实现中理解的内容.

对于==运算符,如果实现了Comparable(并且没有简单标识),它会尝试使用接口方法compareTo,因此使用与其他比较运算符相同的逻辑.只有在没有实现Comparable的情况下,它才会尝试根据某些智能类型调整确定相等性,并且最终比率会回落到调用equals方法.这发生在DefaultTypeTransformation.compareEqual#L603-L608

对于所有其他比较运算符,例如> =,Groovy委托compareToWithEqualityCheck方法.现在调用此方法时将equalityCheckOnly标志设置为false,而对于第一种情况,当调用源自==运算符时,将其设置为true.如果是数字,字符或字符串,还会根据左侧的类型发生一些Groovy智能.如果不适用,则最终在DefaultTypeTransformation.compareToWithEqualityCheck#L584-L586中调用compareTo方法.

现在,只有当这种情况发生时

!equalityCheckOnly || left.getClass().isAssignableFrom(right.getClass())
  || (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass())) //GROOVY-4046
  || (left instanceof GString && right instanceof String)

对于equalityCheckOnly的情况有一些限制,因此当我们来自==运算符时.虽然我无法解释所有这些,但我认为这些是为了防止在特定情况下抛出异常,例如评论中提到的问题.

为简洁起见,我在上面省略了在ScriptBytecodeAdapter中预先处理并且如果左侧和右侧都是相同类型以及Integer,Double或Long之一,则会立即委托为equals的情况.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读