BATCH - 在 for 循环中调用的函数不返回值

Posted

技术标签:

【中文标题】BATCH - 在 for 循环中调用的函数不返回值【英文标题】:BATCH - function called in a for-loop doesn't return value 【发布时间】:2020-01-10 18:36:24 【问题描述】:

我需要使my batch 复杂一点,但它又不起作用了。我需要在循环for /L %%n in (1,1,%s%) do call :TestFunc 中多次调用我的函数(在变量中获取一些值,对其进行更改并返回更改后的值)。

在这个例子中,我想调用一个函数,将值 101 添加到函数调用参数中收到的值,将结果返回给主过程,我想在 for 循环中重复 5 次,将给定的结果放入下一个函数调用的参数。

虽然我的批处理在没有循环的情况下运行良好,但在将函数调用放入这样的循环后它就崩溃了:

SetLocal EnableDelayedExpansion
set "s=5"
set "x=10"
set "y=x"
echo before
echo x = !x!
echo y = !y!
for /L %%n in (1,1,!s!) do (
    call :TestFunc %%n !y! !x!
    echo after
    echo x.2 = !x!, y.2 = !y!
    timeout /t 120
  )
EndLocal
exit /b

:TestFunc
SetLocal EnableDelayedExpansion
set a=%~3
set m=%~1
echo inside
echo a = !a!, m = !m!
set /a a=!a!+101
EndLocal & set "%~2=!a!"
goto :eof

结果是:

>test_variables.bat
before
x = 10
y = x
inside
a = 10, m = 1
after
x.2 = , y.2 = x

waiting 120 s, press any key to continue...
inside
a = , m = 2
after
x.2 = , y.2 = x
...

我预计x 的值将更改为 111、212、313、414 和 515。但如您所见,x (x.2) 的值是“nothing" 离开函数:TestFunc 并返回主程序(在循环内)。因此循环中的下一个函数调用将“无”传递给函数调用参数中的函数,并且函数体内的变量a中一遍又一遍地没有出现任何内容。

在没有循环的情况下调用函数时,离开函数后x 变量的值是 111,正如预期的那样。该工作代码的一个示例放在my post here 的“已编辑”部分。

我知道我可以绕过这个问题,避免使用函数调用并将其主体代码放在 for 循环中,但这只是一个测试示例。在我最终的批处理程序中,它要复杂得多,我需要从不同的代码块多次调用我的函数。

【问题讨论】:

我可能在理解您想要达到的目标时遗漏了一些东西,但我认为在 :TestFunc 中使用 SetLocal EnableDelayedExpansionEndLocal & 没有任何理由。 为什么要在子程序中开启延迟扩展?你实际上不需要它...... 当然我在我的例子中不需要EnableDelayedExpansion :-) 但我在最终的批处理程序中确实需要它,所以我想编写并测试一个启用DelayedExpansion 的简单示例确保它也能在我的目标批处理程序中工作。 @McVik,你能解释一下为什么你需要它吗,因为你在脚本开始时启用它并在结束时结束它,所以在我看来它好像启用了所有时间。 @Compo,那是因为我使用一些循环和过程根据当前系统时间和存储在变量中的其他时间值进行了大量操作。当我不使用EnableDelayedEspansion时,它根本不起作用。 【参考方案1】:

TestFunc 中的倒数第二行应如下所示:

EndLocal & set "%~2=%a%"

解释是你不再在延迟扩展块中,所以!a! 不再存在.. 所以你使用常规的%a% 来获取它的最终值..

【讨论】:

哦,我瞎了眼!愚蠢的我! :-) 当然!非常感谢@wasatchwizard。

以上是关于BATCH - 在 for 循环中调用的函数不返回值的主要内容,如果未能解决你的问题,请参考以下文章

返回函数的返回值的return和结束for循环的return是一个东西吗?

在游标中调用函数 for 循环

在 for 循环中的异步函数调用中有条件地执行回调

使用索引 Batch 在 for 循环中设置变量

Go语言在循环中panic后还能继续执行for循环?

在for循环中同步promises?