Groovy compareTo for CustomClass和数字/字符串
我正在构建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的情况. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |