61

我需要从一个函数中设置一个全局变量,但不太确定如何去做。

# Set variables
$global:var1
$global:var2
$global:var3

function foo ($a, $b, $c)
{
    # Add $a and $b and set the requested global variable to equal to it
    $c = $a + $b
}

调用函数:

foo 1 2 $global:var3

最终结果:

$global:var3 设置为 3

或者,如果我这样调用函数:

foo 1 2 $global:var2

最终结果:

$global:var2 设置为 3

我希望这个例子有意义。传递给函数的第三个变量是要设置的变量的名称。

4

7 回答 7

97

您可以使用Set-Variablecmdlet。传递$global:var3会发送 的$var3这不是您想要的。您要发送的名称

$global:var1 = $null

function foo ($a, $b, $varName)
{
   Set-Variable -Name $varName -Value ($a + $b) -Scope Global
}

foo 1 2 var1

不过,这不是很好的编程习惯。下面会更直接,以后不太可能引入错误:

$global:var1 = $null

function ComputeNewValue ($a, $b)
{
   $a + $b
}

$global:var1 = ComputeNewValue 1 2
于 2012-09-21T18:59:31.040 回答
46

很简单:

$A="1"
function changeA2 () { $global:A="0"}
changeA2
$A
于 2014-05-13T12:28:57.577 回答
24

我在对自己的代码进行故障排除时遇到了这个问题。

所以这不起作用......

$myLogText = ""
function AddLog ($Message)
{
    $myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $myLogText

这似乎可以工作,但仅在PowerShell ISE中:

$myLogText = ""
function AddLog ($Message)
{
    $global:myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $myLogText

这实际上在 ISE 和命令行中都有效:

$global:myLogText = ""
function AddLog ($Message)
{
    $global:myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $global:myLogText
于 2015-05-15T17:21:12.033 回答
18

您必须将参数作为引用类型传递。

#First create the variables (note you have to set them to something)
$global:var1 = $null
$global:var2 = $null
$global:var3 = $null

#The type of the reference argument should be of type [REF]
function foo ($a, $b, [REF]$c)
{
    # add $a and $b and set the requested global variable to equal to it
    # Note how you modify the value.
    $c.Value = $a + $b
}

#You can then call it like this:
foo 1 2 [REF]$global:var3
于 2012-09-21T18:20:50.957 回答
2

latkin 的回答中的第一个建议似乎不错,尽管我会建议下面不那么冗长的方式。

PS c:\temp> $global:test="one"

PS c:\temp> $test
one

PS c:\temp> function changet() {$global:test="two"}

PS c:\temp> changet

PS c:\temp> $test
two

然而,他的第二个建议是关于不好的编程习惯,在像这样的简单计算中是公平的,但是如果你想从你的变量返回一个更复杂的输出怎么办?例如,如果您希望函数返回数组或对象怎么办?对我来说,这就是 PowerShell 函数似乎严重失败的地方。这意味着您别无选择,只能使用全局变量将其从函数传回。例如:

PS c:\temp> function changet([byte]$a,[byte]$b,[byte]$c) {$global:test=@(($a+$b),$c,($a+$c))}

PS c:\temp> changet 1 2 3

PS c:\temp> $test
3
3
4

PS C:\nb> $test[2]
4

我知道这可能感觉有点题外话,但我觉得为了回答最初的问题,我们需要确定全局变量是否是不好的编程习惯,以及在更复杂的函数中是否有更好的方法。(如果有一个我会感兴趣的。)

于 2018-01-09T17:44:07.293 回答
1

@zdan。好答案。我会像这样改进它...

我认为在 PowerShell 中最接近真实返回值的方法是使用局部变量来传递值,并且永远不要使用它,return因为它可能会被任何形式的输出情况“损坏”

function CheckRestart([REF]$retval)
{
    # Some logic
    $retval.Value = $true
}
[bool]$restart = $false
CheckRestart( [REF]$restart)
if ( $restart )
{
    Restart-Computer -Force
}

$restart变量用于函数调用的任一侧,以CheckRestart明确变量的范围。按照惯例,返回值可以是声明的第一个或最后一个参数。我更喜欢最后一个。

于 2015-05-14T02:49:02.350 回答
0

对我来说它有效:

function changeA2 () { $global:A="0"}
changeA2
$A
于 2014-10-30T11:29:51.030 回答