Clear-Variable 和将变量设置为 NULL 之间的区别

Difference between Clear-Variable and setting variable to NULL

我经常使用在脚本作用域中声明的变量来避免函数及其作用域出现问题。我这样声明这些变量:

New-Variable -Name test -Option AllScope -Value $null

...或者有时我像这样切换现有变量以全面使用它们:

$script:test = $test

当我想清除它们时,我要么使用这个:

Clear-Variable test -Scope Script

...或者我只是使用这个:

$test = $null

有区别吗?我应该喜欢什么?为什么?

来自获取帮助:

The Clear-Variable cmdlet deletes the data stored in a variable, but it does not delete the variable. As a result, the value of the variable is NULL (empty). If the variable has a specified data or object type, Clear-Variable preserves the type of the object stored in the variable.

所以 Clear-Variable$var=$null 几乎是等价的(除了保留的打字)。一个完全等价的方法是 $var=[mytype]$null.

你可以自己测试一下:

$p = "rrrr"
Test-Path variable:/p     # => $true
$p = $null
Get-Member -InputObject $p     # => error
$p = [string]$null
Get-Member -InputObject $p   # => it is a string

并回答下一个问题:如何完全删除变量(因为不存在的变量不同于空值变量)?只需做

rm variable:/p
Test-Path variable:/p => $false

补充

注意:为了删除(取消定义)一个变量,使用Remove-Variable <name> [-Scope <scope>].

除非 $test定义为Set-Variable -Option AllScope,

  • Clear-Variable test -Scope Script

  • $test = $null

通常不等同

(With Set-Variable -Option AllScope 它们是,但随后 -Scope 参数变得无关紧要,因为只有 one 变量的实例(概念上)存在于所有范围内。)

$test = $null - 除非在与最初创建变量 test 时相同的范围内执行 - 将隐式 创建 current 范围内的 test 变量(并将 $null 分配给它),并保留 original 变量原封不动。 有关 PS 中变量作用域的更多信息,请参阅我的

请注意,变量赋值语法也提供作用域,通过作用域前缀,但仅限于globalscriptlocal(默认值):$global:test = $null$script:test = $null$local:test = $null

还有 private 作用域:local 的一种变体,可防止 后代作用域 看到变量 - 再次参见.

如果您已确保针对相同的范围,上述两种形式在功能上是等效的: 他们将 $null 分配给目标变量。[1]

但是,使用 Clear-Variable 可以让您做两件 $<scope>:testing = ... 做不到的事情 :

  • -Scope参数也接受一个数字值,表示作用域相对于当前作用域0是当前作用域,1是父作用域,依此类推。

  • 你可以定位多个变量(作为数组名称或使用 通配符)


[1] 陷阱:

请注意,如果目标变量是 类型约束(被分配 "cast notation";例如,[int] $i = 1),类型是 retained - 无论是使用 $testing = $null 还是 Clear-Variable - 并且可能会发生 隐式类型转换 ,可能会产生 意外结果或完全失败

[int] $i = 1 # type-constrain $i as an integer
Clear-Variable i # equivalent of $i = $null
$i # !! $i is now 0 (!), because [int] $null yields 0

[datetime] $d = 1 # type-constrain $d as DateTime
Clear-Variable d # !! FAILS, because `$d = $null` fails, given that 
                 # !! $null cannot be converted to [datetime]