引用全局变量时是否可以选择使用$ global:scope前缀?

时间:2019-01-22 21:03:09

标签: powershell

如果我使用$global:MyVariable = "123"声明并初始化PowerShell变量,那么我是否需要使用$ global:在使用该变量的任何地方还是可以只使用$ MyVariable?

3 个答案:

答案 0 :(得分:3)

  • 原则上,您可以仅使用$MyVariable来通过该名称引用全局变量的值,但是您可能会看到视情况而定另一个变量的值

  • 具体来说,如果任何介入的祖先(父)范围,甚至调用范围本身也已经 创建了{{1 }}变量(通常通过简单的 assigmnent 隐式发生 ;例如$MyVariable),您会看到那个变量的值。

  • 如果您确实使用了全局作用域说明符,则您只能保证查看全局值,即:$MyVariable = ...(或$global:MyVariable [1]

  • 默认情况下,变量在所有后代(子级)范围内都是可见的,但不能直接可修改

    • 因此,您必须使用Get-Variable -ValueOnly -Scope Global MyVariable / $global:MyVariable修改(设置)全局变量;如果没有Set-Variable -Scope Global,您将隐式创建一个具有相同名称的 local 变量。
    • 有关PowerShell范围规则的更多信息,请参见this answer的最后一部分。

[1]在实际场景中,即使在PowerShell 模块中的代码也可以看到具有范围说明符$global:的全局变量,以及对始终可见的全局变量的隐式可见性适用。

对于内存中模块,有一种 方法可以使$global: / $global引用不同的作用域,即模块自己的顶级范围,但该技术是模糊的,没有记录,其实际用途还未知。
如果您想了解更多,请继续阅读。


可选读物:创建一个内存模块,将其自身的顶级范围视为全局范围:

PetSerAl发现了一种鲜为人知的创建内存模块的方法,该方法使其将-Scope global / $global:视为其自身的顶级范围。 而不是真正的全局范围-奇怪的是, not 使用显式范围引用使代码仍然可以看到(非阴影的)全局变量:

-Scope global

产量:

$global:MyVariable = 42 # Create a true global variable.

# Create an in-memory module for which its *own top-level scope*
# becomes the "global" scope, by virtue of passing $false to the
# [psmoduleinfo] constructor:
& ([psmoduleinfo]::new($false)) {
  @"
   '$global:MyVariable',
   '$(Get-Variable -ValueOnly -Scope global MyVariable)',
   '$MyVariable'
"@
}

请注意,Get-Variable : Cannot find a variable with the name 'MyVariable'. # ... '', # $global:MyVariable didn't find the variable '', # Neither did Get-Variable -Scope Global (see error above) '42' # OK - implicit visibility of true global variables New-Module(对于持久化模块)均不提供此功能。

this excellent blog postPatrick Meinecke中解释了上面用于在模块范围内调用脚本块的模糊Import-Module技术。

答案 1 :(得分:2)

运行此命令,发现最好始终指定,否则,始终不会得到期望的结果

function func {
    "0. $myvar"
    $myvar='funclocal'
    "1. $myvar"
    "2. $Global:myvar"
}
$Global:myvar='global'
func
"3. $Global:myvar"

答案 2 :(得分:-3)

调用时无需使用$ global: