为什么Groovy中的加号运算符重载对字符串不起作用?

zzzyeukh  于 8个月前  发布在  其他
关注(0)|答案(1)|浏览(57)

我能够为我的类实现一个操作符覆盖,但我无法以任何方式为String实现它。为什么?为什么?

static void main(String[] args) {
    String.metaClass.plus = {
        r -> return "-";
    }

    print "left" + "right"
}


//I tried and so:
static void main(String[] args) {
    String.metaClass.plus = {
        r -> return "-".toString();
    }

    print "left".toString() + "right".toString()
}

Example from Groovy online compiler

更新。

我设法达到了预期的结果。我只是将String类型添加到匿名函数参数中。

//Old - non-working version.
String.metaClass.plus = {
    r -> "-";
}

//New - working version.
String.metaClass.plus = {
    String r -> "-";
}

问题仍然是一样的,为什么旧版本不起作用,而新版本起作用?在我正在观看的课程中,一切都很好,ChatGPT也说一切都应该工作。

zvokhttg

zvokhttg1#

Groovy已经重载了plus(您看到的行为)。
您的版本String.metaClass.plus = { "-" }意味着此版本:String.metaClass.plus = { Object it -> "-" }(默认情况下,groovy闭包有一个默认的单个参数it,其类型为Object(或groovy中的def)。
所以现在String上有两个plus,JVM在调用它时选择最佳匹配(工作中的多态性)。这不是你的,因为ObjectCharSequence更通用。
所以你可以像这样强迫你的版本:

static void main(String[] args) {
    String.metaClass.plus = { "-" }
    print "left" + 42 // ⇒ -
}

将参数的类型强制为String--就像您在工作示例中所做的那样--使您的函数在使用String参数(也可能是任何参数,因为Groovy可能会强制)调用时成为所选择的函数。
注:
编写闭包,如

{
    String r -> "-"
}

对读者来说是非常误导的。参数通常与左大括号保持在一行中。

{ String r -> 
    "-"
}

相关问题