Different behavior of Groovy's 'name : expression' syntax

Viewed 83

I make myself familiar with groovy and am a little surprised that the following code runs:

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

What is abc : 1 ? I think it might be a map as the following code:

class Main {

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

}

leads to [abc:1] being printed to the console, but

class Main {

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

}

compiles not!!! But the most confusing part is that wrapping the expression into a closure

class Main {

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

}    

leads to 1 being printed to the console and not [abc:1]. Is there any use of the colon I am not aware of?

1 Answers

There are 2 different usage context in your example.

1. Named parameters

In the first example, you've used Groovy's named parameters. The following Groovy code:

print(abc: 1)

is an equivalent of

print([abc: 1])

Groovy uses a map to represent named arguments and this construction is available only in the method invocation. That is why when you have tried assigning abc : 1 to a variable, compilation failed with an error.

2. Labeled statements

The second example that uses a closure is an example of labeled statement. If you format your code it would look like this:

def closure = { ->
    abc:
    return 1 // return is optional of course in this case. I added it to make the example more explicit
}

print closure() // prints 1

Keep in mind that labels have no impact on the semantics of the code, that is why you get 1 in return. Labels are present in the abstract syntax tree and they can be used to manipulate the code (e.g. Spock Framework uses labels like given, when, then to add specific behavior to a test).

Related