问题描述
我已经阅读了很多有关使用变量从批处理函数返回值的示例和问题,但是我不能强迫Windows 7 x64 cmd.exe为我完成此任务. ;-)
I have read a lot of examples and questions about returning values from batch functions using variables but I can't force Windows 7 x64 cmd.exe to do it for me. ;-)
我已经尝试了很多代码示例,但是没有任何工作像我预期的那样.我写了一个简短的批处理程序来找出如何做,但是它也没有按我预期的那样工作.我找不到我在做错什么.
I have already tried a lot of code examples but nothing has worked as I expected. I have written a short batch program to find out how to do it, but it also hasn't worked as I expected. I can't find what I'm doing wrong.
@echo off
SetLocal EnableDelayedExpansion
set x=10
echo x(1) = !x!
call :TestFunc !x!
echo x(2) = !x!
EndLocal
exit /b
:TestFunc
SetLocal EnableDelayedExpansion
set a=%~1
echo a(1) = !a!
set /a a=a+101
echo a(2) = !a!
set %~1=!a!
echo %%~1 = %~1
echo ^^!%%~1^^! = !%~1!
EndLocal
exit /b
我希望set %1=!a!
将设置:TestFunc
返回的唯一变量.但是结果是:
I expected that set %1=!a!
will set the only variable being returned by the :TestFunc
. But the result is:
>test_variables.bat
x(1) = 10
a(1) = 10
a(2) = 111
%~1 = 10
!%~1! = 111
x(2) = 10
对我来说,最令人惊讶的是:TestFunc
主体中有两个变量%~1
-一个是在本地设置的,另一个是传递给函数的,也可能由函数返回,但未更改在功能主体内部.
The most surprising for me was that there are two variables %~1
inside the body of the :TestFunc
- one is set locally and the other one, passed to the function and maybe also returned by the function, but not changed inside the function's body.
修改
最后,感谢@Stephan,我的工作正常了:
And finally, thanks to @Stephan, my exaple that is working:
@echo off
rem echo on
SetLocal EnableDelayedExpansion
set "x=10"
set "y=x"
echo x(1) = !x!
echo y(1) = !y!
call :TestFunc !y! !x!
echo ---------------------------------
echo x(2) = !x!
echo y(2) = !y!
EndLocal
exit /b
:TestFunc
SetLocal EnableDelayedExpansion
set a=%~2
echo a(1) = !a!
set /a a=!a!+101
echo a(2) = !a!
EndLocal & set "%~1=%a%"
exit /b
和结果:
>test_variables.bat
x(1) = 10
y(1) = x
a(1) = 10
a(2) = 111
---------------------------------
x(2) = 111
y(2) = x
有两个技巧:
- 将第一个变量名称(x)放入另一个变量(y)值,并以两个变量名称作为参数调用该函数
- @Stephan的设置在子句(
EndLocal & set "%~1=%a%"
)之后返回变量值的技巧.
- Put the first variable name (x) into the other variable (y) value and call the function with both variable names as parameters
- @Stephan's trick with setting returned variable value after the
EndLocal
clause (EndLocal & set "%~1=%a%"
).
推荐答案
set %~1=!a!
设置一个由%~1
值(在您的示例中为10
)命名的变量.因此命令被解析为:set 10=111
set %~1=!a!
sets a variable named by the value of %~1
(which is 10
in your example). so the command is parsed as: set 10=111
(您不应使用以数字开头的变量名)
(you shouldn't use variablenames starting with a digit)
我想你要做的是:
echo on
set "var=xxx"
call :sub var 10
echo %var%
goto :eof
:sub
setlocal
set /a tmpvar=%~2+55
endlocal & set "%~1=%tmpvar%"
我离开了echo on
,以查看解析器如何翻译"您的代码.
I left echo on
to see exactly, how the parser "translates" your code.
主要技巧是使变量在endlocal
中生存.这是通过用行endlocal & set "%~1=%tmpvar%
欺骗解析器来实现的; %tmpvar%
实际上是在 endlocal
生效之前评估的.
The main trick is for the variable to survive an endlocal
. This is achieved by tricking the parser with the line endlocal & set "%~1=%tmpvar%
; %tmpvar%
is actually evaluated before endlocal
takes effect.
这篇关于BATCH-无法从函数的变量中返回正确的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!