批量 - 通过延迟扩展获取本地值

Batch - Get value of local with delayed expansion

在下面的代码中,我创建了一些伪数组(表示对)并调用了一个例程,该例程获取伪数组的名称及其大小作为参数值。在例程中,我想循环访问每个数组元素。据我所知,访问数组值的唯一可能性是使用延迟扩展,如果我可以在本地取回延迟扩展的值,这将不是问题。

@ECHO OFF
    SETLOCAL DISABLEDELAYEDEXPANSION
        set pairs[0]="a" "b"
        set pairs[1]="c" "d"
        set pairs[2]="e" "f"
        set pairNumber=3

        call :my_routine pairs %pairNumber%
    ENDLOCAL
EXIT /B 0

:my_routine
    SETLOCAL DISABLEDELAYEDEXPANSION
        set myPairs=%1
        set /a maxCount=%2-1

        for /l %%c in (0,1,%maxCount%) do (
            set "currentPair="
            SETLOCAL ENABLEDELAYEDEXPANSION
                call set "pair=%%!myPairs![%%c]%%"
                REM setting the value works:
                REM echo !pair!
            ENDLOCAL & set "currentPair=%pair%"
            echo %currentPair%
        )
    ENDLOCAL
exit /b 0

预期输出:

"a" "b"
"c" "d"
"e" "f"

关键的部分是& set currentPair=%pair%。据我了解,未设置 %pair% 值是因为在设置时使用了延迟扩展。

问题是关于取回价值,而不是告诉我我可以在当地做事。如果没有办法取回价值,我会考虑这一点。

我也看过 this 非常相似的问题,但解决方案对我不起作用。

所以...

如何从内部本地中获取值,以便 currentPair 获取 pair 的值?

我敢肯定这不是你想要的;但根据您提供的有限信息和已知的字符串内容,无需在 For /L 循环中设置不必要的变量或启用和禁用延迟扩展。

@Echo Off
SetLocal DisableDelayedExpansion

Set "pairs[0]="a" "b""
Set "pairs[1]="c" "d""
Set "pairs[2]="e" "f""
Set "pairNumber=2"

Call :my_routine pairs %pairNumber% currentPair

Exit /B 0

    :my_routine
    SetLocal EnableDelayedExpansion

    For /L %%A In (0,1,%2) Do Set "%3=!%1[%%A]!" & Echo !%3!

    Pause

    Exit /B 0

如果需要,您可以选择将 Echo !%3! 更改为 Set %3
每个 SetLocalEndLocal 及其各自的 Exit

将变量值传递到 endlocal 屏障之外的通常方法依赖于这样一个事实,即它没有放在代码块中,而是将行 endlocal & set "currentPair=%pair%" 放在 for /L循环。

您可以改用 for /F 循环,如下所示:

for /F "delims=" %%E in (""!pair!"") do (
    endlocal
    set "currentPair=%%~E"
)

!pair! 周围的一对引号告诉 for /F 它是一个文字字符串;内部对是该字符串的一部分,然后由 %%~E 中的 ~ 修饰符删除。这样做的目的是确保循环始终迭代一次(即使 !pair! 为空),因此 endlocal 被执行。

这也适用于另一个代码块,例如您的 for /L 循环。

当然 echo %currentPair% 行不是 return 正确的字符串,但您可以将 echo(%%~E 放在 for /F 循环中。