Powershell添加到函数中的数组不像我想的那样工作

时间:2015-05-21 19:42:40

标签: powershell

当我在函数中添加数组时,它在ISE中工作,但在命令窗口中它不会添加。

    Clear
    $array = @()

    FUNCTION AddtoArray() {
        Write "start of function"
        $array
        $global:array += "c "
        Write "result of add to array function"
        $array
    }

    $array = "a "
    Write "New array"        
    $array
    $array += "b "        
    Write "Add to array"
    $array
    AddtoArray
    Write "Back from Function"
    $array    

当我在PowerGUI或PS ISE中运行时,我得到:

a b

a b

a b c

a b c

当我从Powershell命令窗口运行时,我得到:

a b

a b

a b

a b

从PS cmd窗口调用脚本时,函数+ =不添加“c”。当我在没有$ global:array + =“c”的情况下运行它时,它可以在PowerGui中运行,但是PS ISE将仅返回添加并丢失“a b”。

1 个答案:

答案 0 :(得分:2)

Global范围代表任何会话的最高范围,当您打开提示并指定$a = "123"时,您就会隐式写入$Global:a

但是当你启动一个脚本时,例如:

PS C:\> # Inside our global scope here at the prompt we just opened
PS C:\> .\TestAddToArray.ps1
a 
a b
a b
a b
a b
PS C:\>

TestAddToArray.ps1文件中的任何变量赋值都默认为Script范围 - 在该脚本文件中的所有变量和函数之间共享,但仍然是Global范围内的子范围1}}。

因此,当您首次初始化$array时,您认为$array表示$Global:array,但根据执行上下文,它实际上可能意味着$Script:array(跳过重复项)输出):

PS C:\> # Inside our global scope here at the prompt we just opened
PS C:\> .\TestAddToArray.ps1
a   # $Script:array is now "a" - $Global:array doesn't exist
a b # $Script:array is now "a ","b " - $Global:array doesn't exist
a b # $Script:array is still "a ","b " - $Global:array is now "c "
PS C:\>

作为实验,请尝试拨打4-5次脚本,然后输入$Global:array并查看添加了多少"c "

PowerShell中使用的动态范围模型可能有点令人困惑,但在帮助文件中对它进行了很好的解释:

Get-Help about_Scopes -Full | more

正如帮助文件所提到的,您可以通过提供[int]作为-Scope参数参数来引用祖先范围(其中0表示本地/当前范围,1是直接父范围等。),这里有一个强大的解决方法":

function AddToArray {
    $temp = (Get-Variable -Name array -Scope 1).Value
    $temp += "c "
    Set-Variable -Name array -Scope 1 -Value $temp
}

现在,如果从全局范围定义并调用AddToArray,它将回写到$ Global:array(直接父范围),但如果它发生在脚本文件中,它现在写回$Script:array,因为Script范围是此上下文中的直接父范围。

然后脚本变为:

clear
$array = @()

function AddtoArray {
    Write "start of function"
    $array
    $temp = (Get-Variable -Name array -Scope 1).Value
    $temp += "c "
    Set-Variable -Name array -Scope 1 -Value $temp
    Write "result of add to array function"
    $array
}

$array = "a "
Write "New array"        
$array
$array += "b "        
Write "Add to array"
$array
AddtoArray
Write "Back from Function"
$array 

无论是否将其粘贴到命令行,从嵌套提示符执行,单独的脚本文件,ISE中的编辑器(您明白了),您都会发现输出是一致的