如果我使用$global:MyVariable = "123"
声明并初始化PowerShell变量,那么我是否需要使用$ global:在使用该变量的任何地方还是可以只使用$ MyVariable?
答案 0 :(得分:3)
原则上,您可以仅使用$MyVariable
来通过该名称引用全局变量的值,但是您可能会看到视情况而定另一个变量的值。
具体来说,如果任何介入的祖先(父)范围,甚至调用范围本身也已经 创建了{{1 }}变量(通常通过简单的 assigmnent 隐式发生 ;例如$MyVariable
),您会看到那个变量的值。
如果您确实使用了全局作用域说明符,则您只能保证查看全局值,即:$MyVariable = ...
(或$global:MyVariable
) [1]
默认情况下,变量在所有后代(子级)范围内都是可见的,但不能直接可修改。
Get-Variable -ValueOnly -Scope Global MyVariable
/ $global:MyVariable
来修改(设置)全局变量;如果没有Set-Variable -Scope Global
,您将隐式创建一个具有相同名称的 local 变量。 [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 post在Patrick 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: