Groovy的“ name:expression”语法的不同行为

Sam*_*raf 3 groovy

我使自己熟悉groovy,并且对以下代码运行感到有些惊讶:

class Main {
    static void main(String[] args) {
        abc : 1
    }
}
Run Code Online (Sandbox Code Playgroud)

什么abc : 1啊 我认为这可能是一张地图,如下所示:

class Main {

    static void main(String[] args) {
        print(abc : 1)
    }

}
Run Code Online (Sandbox Code Playgroud)

导致[abc:1]被打印到控制台,但是

class Main {

    static void main(String[] args) {
        def map = abc : 1
    }

}
Run Code Online (Sandbox Code Playgroud)

不编译!!!但最令人困惑的部分是将表达式包装到闭包中

class Main {

    static void main(String[] args) {
        def closure = {-> abc : 1}
        print closure()
    }

}    
Run Code Online (Sandbox Code Playgroud)

导致1被打印到控制台而不是[abc:1]。我不知道有没有使用结肠?

Szy*_*iak 5

您的示例中有2种不同的用法上下文。

1.命名参数

在第一个示例中,您使用了Groovy的named参数。以下Groovy代码:

print(abc: 1)
Run Code Online (Sandbox Code Playgroud)

等价于

print([abc: 1])
Run Code Online (Sandbox Code Playgroud)

Groovy使用映射表示命名的参数,并且此构造仅在方法调用中可用。这就是为什么当您尝试分配abc : 1给变量时,编译失败并显示错误的原因。

2.带标签的陈述

使用闭包的第二个示例是带标签声明的示例。如果格式化代码,则其格式如下:

print(abc: 1)
Run Code Online (Sandbox Code Playgroud)

请记住,标签对代码的语义没有影响,这就是为什么您会得到1回报。标签存在于抽象语法树,它们可以被用来操纵代码(例如斯波克框架使用的标签一样givenwhenthen具体的行为添加到测试)。