gpt4 book ai didi

jenkins - Groovy 中的闭包不捕获外部变量

转载 作者:行者123 更新时间:2023-12-03 21:19:20 25 4
gpt4 key购买 nike

在 Jenkins 管道的上下文中,我有一些 Groovy 代码枚举一个列表、创建闭包,然后在闭包中使用该值作为在映射中查找另一个值的键。这似乎几乎每次都充斥着某种异常或竞争状况。

这是代码的简化:

def tasks = [:]
for (platformName in platforms) {
// ...

tasks[platformName] = {
def componentUploadPath = componentUploadPaths[platformName]

echo "Uploading for platform [${platformName}] to [${componentUploadPath}]."

// ...
}

tasks.failFast = true
parallel(tasks)
platforms有两个值。我通常会看到两个迭代和两个注册的任务以及 tasks 中的键。将是正确的,但闭包内的 echo 语句表明我们只是在其中一个平台上运行了两次:
14:20:02 [platform2] Uploading for platform [platform1] to [some_path/platform1].
14:20:02 [platform1] Uploading for platform [platform1] to [some_path/platform1].

这太荒谬了。

我需要添加什么或做些什么?

最佳答案

这与您在 Javascript 中看到的问题相同。

当您在 for 循环中生成闭包时,它们被绑定(bind)到一个变量,而不是变量的值。

当循环退出并运行闭包时,它们都将使用相同的值......即 - for 循环中退出之前的最后一个值

例如,您希望打印 1 2 3 4 ,但它没有

def closures = []

for (i in 1..4) {
closures << { -> println i }
}

closures.each { it() }

它打印 4 4 4 4
要解决此问题,您需要做以下两件事之一...首先,您可以在本地范围的变量中捕获值,然后关闭此变量:
for (i in 1..4) {
def n = i
closures << { -> println n }
}

您可以做的第二件事是使用 groovy 的 eachcollect因为每次调用它们时,变量都是一个不同的实例,所以它再次起作用:
(1..4).each { i ->
closures << { -> println i }
}

对于您的情况,您可以遍历 platforms并同时使用 collectEntries 收集到 map 中:
def tasks = platforms.collectEntries { platformName ->
[
platformName,
{ ->
def componentUploadPath = componentUploadPaths[platformName]
echo "Uploading for platform [${platformName}] to [${componentUploadPath}]."
}
]
}

希望这可以帮助!

关于jenkins - Groovy 中的闭包不捕获外部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56348341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com