问题
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