BATCH - 无法从函数的变量中返回正确的值 [英] BATCH - can't return proper value in a variable from a function

查看:31
本文介绍了BATCH - 无法从函数的变量中返回正确的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多关于使用变量从批处理函数返回值的示例和问题,但我无法强制 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

有两个技巧要做:

  1. 将第一个变量名 (x) 放入另一个变量 (y) 值中,并以两个变量名作为参数调用函数
  2. @Stephan 在 EndLocal 子句之后设置返回变量值的技巧(EndLocal & set "%~1=%a%").
  1. Put the first variable name (x) into the other variable (y) value and call the function with both variable names as parameters
  2. @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% 实际上是在 before 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 - 无法从函数的变量中返回正确的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆