引用全局变量时是否可以选择使用 $global: 范围前缀? [英] Is it optional to use the $global: scope prefix when referencing a global variable?
问题描述
如果我使用 $global:MyVariable = "123"
声明并初始化一个 PowerShell 变量,那么我是否需要使用 $global: 任何使用该变量的地方,还是可以只使用 $MyVariable?
If I declare and initialize a PowerShell variable with $global:MyVariable = "123"
do I then need to use $global: anywhere I use the variable or can I just use $MyVariable?
推荐答案
原则上你可以只使用
$MyVariable
来引用一个全局变量的值,但您可能会看到不同的变量值,视情况而定.In principle you can use just
$MyVariable
to reference the value of a global variable by that name, but you may see a different variable's value, situationally.具体来说,如果任何介入的祖先(父)范围甚至调用范围本身也创建了一个
$MyVariable
变量(通常通过简单的赋值隐式发生;例如,$MyVariable = ...
),你会看到那个变量的值.Specifically, if any intervening ancestral (parent) scope or even the calling scope itself has also created a
$MyVariable
variable (which typically happens implicitly by simple assigmnent; e.g.,$MyVariable = ...
), you will see that variable's value instead.如果您确实使用了全局范围说明符,即:
$global:MyVariable
(或Get-Variable -ValueOnly -Scope Global MyVariable
)[1]You're only guaranteed to see the global value if you do use the global scope specifier, namely:
$global:MyVariable
(orGet-Variable -ValueOnly -Scope Global MyVariable
)[1]默认情况下,变量在所有后代(子)范围内可见,但不能直接修改.
By default, variables are visible, but not directly modifiable in all descendant (child) scopes.
- 因此您必须使用
$global:MyVariable
/Set-Variable -Scope Global
以便修改(设置)一个全局变量;如果没有$global:
,您将隐式创建一个同名的 local 变量. - 有关 PowerShell 范围规则的更多信息,请参阅此答案的最后一部分.
- Therefore you must use
$global:MyVariable
/Set-Variable -Scope Global
in order to modify (set) a global variable; without$global:
you'll implicitly create a local variable by the same name. - For more on PowerShell's scoping rules, see the last section of this answer.
[1] 在实际场景中,即使是 PowerShell modules 中的代码也会看到带有作用域说明符
$global:
的全局变量,以及全局变量的隐式可见性总是适用.[1] In real-world scenarios, even code in PowerShell modules sees global variables with scope specifier
$global:
, and the implicit visibility of global variables always applies.对于内存模块,有一种方法可以让
$global
/-Scope global
引用一个不同的范围,即模块自己的顶级作用域,但该技术晦涩难懂,没有记录,其实际效用未知.
如果您想了解更多信息,请继续阅读.For in-memory modules, there is a way to make
$global
/-Scope global
refer to a different scope, namely the module's own top-level scope, but the technique is obscure, not documented, and its real-world utility is unknown.
Read on, if you want to know more.可选阅读:创建一个将自己的顶级范围视为全局范围的内存模块:
Optional reading: Creating an in-memory module that sees its own top-level scope as the global scope:
PetSerAl 发现了一种鲜为人知的方法来创建内存模块,使其能够看到
$global:
/-Scope global
作为其自己的顶级范围而不是真正的全局范围 - 奇怪的是,不是 使用显式范围引用使代码仍然可以看到(非阴影)全局变量:PetSerAl has discovered a little-known way to create an in-memory module in a manner that makes it see
$global:
/-Scope global
as its own top-level scope rather than the true global scope - curiously, not using an explicit scope reference makes the code still see (non-shadowed) global variables:$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
和Import-Module
(对于 persisted 模块)都没有提供此功能.Note that neither
New-Module
norImport-Module
(for persisted modules) offer this functionality.晦涩的
&<模块信息>{ ... }
上面用于在模块范围内调用脚本块的技术在 这篇优秀的博文 作者:Patrick Meinecke.The obscure
& <module-info> { ... }
technique used above for invoking a script block in a module's scope is explained in this excellent blog post by Patrick Meinecke.这篇关于引用全局变量时是否可以选择使用 $global: 范围前缀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 因此您必须使用