Difference between Clear-Variable and setting variable to NULL

北战南征 提交于 2021-02-07 13:17:33

问题


I often use variables which are declared in the script scope to avoid problems with functions and their scopes. I am declaring these variables like this:

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

... or sometimes I switch existing variables like this to use them comprehensively:

$script:test = $test

When I want to clear them I either use this:

Clear-Variable test -Scope Script

... or I simply use this:

$test = $null

Is there a difference? What should I prefer and why?


回答1:


From the get-Help:

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.

So Clear-Variable and $var=$null are nearly equivalents (with the exception of the typing which is retained). An exact equivalent would be to do $var=[mytype]$null.

You can test it yourself:

$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

And to answer what may be the next question: how to completely remove a variable (since an absent variable is different from a null-valued variable)? Simply do

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



回答2:


To complement Marcanpilami's helpful answer:

Note: In order to remove (undefine) a variable altogether, use Remove-Variable <name> [-Scope <scope>].

Unless $test is defined with Set-Variable -Option AllScope,

  • Clear-Variable test -Scope Script

and

  • $test = $null

are NOT generally equivalent.

(With Set-Variable -Option AllScope they are, but then the -Scope argument becomes irrelevant, because then only one instance of the variable exists (conceptually), across all scopes.)

$test = $null - unless executed in the same scope as when variable test was originally created - will implicitly create a test variable in the current scope (and assign $null to it), and leave the original variable untouched. For more on variable scoping in PS, see this answer of mine.

Note that variable-assignment syntax offers scoping too, via a scope prefix, but it is limited to global, script, and local (the default): $global:test = $null, $script:test = $null, $local:test = $null

There's also the private scope: a variation of local that prevents descendant scopes from seeing a variable - again, see this answer.

If you've ensured that you are targeting the same scope, the two forms above are functionally equivalent: they assign $null to the target variable.[1]

However, using Clear-Variable allows you to do two things that $<scope>:testing = ... doesn't:

  • the -Scope parameter also accepts a numeric value that indicates the scope relative to the current scope: 0 is the current scope, 1 is the parent scope, and so on.

  • you can target multiple variables (either as an array of names or using wildcards)


[1] Pitfall:

Note that if the target variable is type-constrained (was assigned with "cast notation"; e.g., [int] $i = 1), the type is retained - whether using $testing = $null or Clear-Variable - and an implicit type conversion may occur, which can have unexpected results or fail altogether:

[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]


来源:https://stackoverflow.com/questions/37568027/difference-between-clear-variable-and-setting-variable-to-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!