Batch file 批处理—在for循环中调用的函数不';t返回值

Batch file 批处理—在for循环中调用的函数不';t返回值,batch-file,for-loop,variables,windows-7,Batch File,For Loop,Variables,Windows 7,我需要把事情复杂化一点,但还是不行。我需要在一个循环中调用我的函数(该函数在变量中获取一些值,然后对其进行更改并返回更改后的值)s次for/L%%n in(1,1,%s%)do call:TestFunc 在本例中,我想调用一个函数,将函数调用参数中接收到的值加上101,将结果返回到主过程,然后在for循环中重复5次,将给定结果放入下一个函数调用的参数中 虽然我的批处理在没有循环的情况下运行良好,但在将函数调用放入如下循环后,它就崩溃了: SetLocal EnableDelayedExpans

我需要把事情复杂化一点,但还是不行。我需要在一个循环中调用我的函数(该函数在变量中获取一些值,然后对其进行更改并返回更改后的值)s次
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
EndLocal & set "%~2=%a%"
结果是:

>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)的值在离开函数
:TestFunc
并返回到主过程(在循环内部)后为“nothing”。因此,循环中的下一个函数调用将“nothing”传输到函数调用参数中的函数,并且函数体中的变量
a
中一次又一次没有显示任何内容

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


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

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

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
EndLocal & set "%~2=%a%"

原因是您不再处于延迟扩展块中,因此
!a不再存在。。因此,您可以使用常规的
%a%
来获取其最终值

我可能在理解您试图实现的目标时遗漏了一些东西,但我认为使用
SetLocal EnableDelayedExpansion
EndLocal&
内部
:TestFunc
没有任何理由。为什么在子例程中启用延迟扩展?您实际上不需要它…当然,我不需要在我的示例中启用延迟扩展,但我在最后一个批处理程序中确实需要它,所以我想编写并测试一个启用了延迟扩展的简单示例,以确保它也能在我的目标批处理程序中工作。@McVik,您能解释一下为什么需要它吗?因为您在脚本开始时启用了它,在脚本结束时又结束了它,所以在我看来,它似乎一直处于启用状态。@Compo,这是因为我使用一些循环和过程,根据当前系统时间和存储在变量中的其他时间值执行许多操作。当我没有使用
EnableDelayedEspansion
时,它根本不起作用。哦,我瞎了!愚蠢的我!:-)当然非常感谢@wasatchwizard。