The <<
is a left-shift operator. In this scenario, task "task$counter"
is a Task
object declaration, and <<
is overloaded as an alias to the doLast
method, which appends the closure to the list of actions to perform when executing the task.
If you don't specify the <<
, the closure is treated as a configuration closure and will be executed by default during the configuration phase of your project's build lifecycle, regardless of whatever task argument is given on the command line.
Example:
If you take the configuration specified in the question:
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
And run gradle task3
, the output will be:
:task3
I'm task number 3
Because each closure was defined to be an execution action specific to the task. Since task3
was named as the task to execute, that was the only action closure executed.
But if you remove the <<
and make the configuration as follows:
4.times { counter ->
task "task$counter" {
println "I'm task number $counter"
}
}
And run gradle task3
, the output will then be:
I'm task number 0
I'm task number 1
I'm task number 2
I'm task number 3
:task3 UP-TO-DATE
This is because all closures were defined to configure the tasks themselves, not be executed as actions when running the tasks. So in this case, Gradle executed all of the closures while configuring the project, then when it came time to execute task3
, there were no actions to perform, so it reported the task as UP-TO-DATE
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…