因此,可以使用Clear-Variable
cmdlet清除变量,该变量与为其赋予值$null
相同。
还可以使用Remove-Variable
cmdlet或Remove-Item
cmdlet删除环境变量的变量。
我的问题是,像这样将变量串在一起...
$Env:var1 = $var2 = $var3 = $null
...清除变量甚至分配值的合法方法?
我知道$var1
与$var2
是独立的,如果您分配如下值:$var1 = $var2 = 1
,但是当该值是使用New-Object
cmdlet创建的对象时,两者变量指向同一对象:
$var1 = $var2 = New-Object System.Diagnostics.Stopwatch
$var1.Start()
Start-Sleep 1
$var2.Stop()
Start-Sleep 1
$var1.Elapsed.TotalMilliseconds
这仅仅是降低值是Microsoft .NET Framework
还是COM object
吗?
答案 0 :(得分:4)
...清除变量的合法方法
是的,类似于 $var1 = $var2 = $null
(仅使用 2 变量为例)是清除变量值的合法方法,已提供实际上,目标变量是在 local (当前)范围内定义的。
如果它们仅在 parent (祖先)范围内可见,您将无意中创建名称为$null
的同名 local 变量-参见this answer。
原则上同样适用于 Clear-Variable var1, var2
,不同之处在于,如果没有 local 变量,它将发出 error 错误$var1
和$var2
被定义;此外,Clear-Variable
允许使用-Scope
显式地定位其他范围。
有限制,您还可以使用诸如$script:var
-参见this related answer之类的范围说明符,通过变量分配来定位其他范围。
Remove-Variable
的行为与Clear-Variable
类似,并且还支持-Scope
,但实际上是从隐含的或目标范围。
请注意,默认情况下访问已删除/不存在的变量 与访问值为$null
的现有变量实际上是相同的。
但是,实际上,Set-StrictMode -Version 1
或更高版本的访问不存在的变量在设计上会失败。
$var1 = $var2 = $null
相对于Clear-Variable var1, var2
具有以下优势:
$null
值的变量 ,或者换句话说,如果其中一个变量不存在,则语句不会失败。 $env:FOO
)一起使用,尽管请注意,将$null
(或''
,空字符串)分配给环境变量实际上删除了($env:FOO = $null
等效于Remove-Item Env:FOO
)。 注意事项:
分配$null
或调用Clear-Variable
不一定会导致变量包含$null
:
变量可能受类型约束 ,在这种情况下,它们仅允许存储在创建(初始化)时锁定的类型的值:
[int] $i = 1 # Create a type-constrained variable that can only store [int] values.
当您将$null
分配给类型约束的变量时,PowerShell尝试将 $null
转换为锁定类型,这可能有两个结果:
转换成功,在这种情况下,锁定类型的转换后的值为新值;例如,对于[int]
,该值为0
,因为[int] $null
为0
。
[int] $i = 1; $i = $null; $i # -> 0, not $null
转换可能失败,从而导致错误;对于[datetime]
,转换失败,因为[datetime] $null
失败。
# !! ERROR: Cannot convert null to type "System.DateTime"
[datetime] $dt = Get-Date; $dt = $null
与New-Object
一样,并为多个变量分配 non-null 值:
如评论中所述,最终行为归结于是分配了value-type实例还是reference-type实例 [1] :
使用 value-type 实例,每个变量都会获得其自己的值独立副本。
# A value-type instance such as an [int] instance assigns
# *independent copies* of itself to the target variable(s):
$var1 = $var2 = 42; $var2 = 43; $var1, $var2 # -> 42, 43
使用 reference-type 实例,所有变量都真正引用同一对象。
# A reference-type instance such as a [hashtable] instance assigns
# a *reference to itself* to the target variable(s), which therefore
# all reference the same object.
$var1 = $var2 = @{one=1}; $var2.one = 2; $var1.one, $var2.one # -> 2, 2
请注意, [string]
实例是一个例外情况:[string]
从技术上讲是 reference 类型,但具有 value 类型的语义,以便提供更直观的字符串处理-请参见this answer。
New-Object
可以实例化这两种类型:如果给它指定值类型的名称,则会得到一个值类型实例;给定引用类型的名称,您将获得一个引用类型实例。
但是,由于内置值类型可以用文字(例如,1
)或简单的类型转换([int]
)实例化,因此更常用New-Object
实例化引用类型。
[1]给定类型或实例,您可以检查类型的.IsValueType
属性,以确定它是否是值类型;例如,由于[int]
(System.Int32
)是值类型[int].IsValueType
,而(1).GetType().IsValueType
产生$true
,而[System.IO.FileInfo].IsValueType
是$false
,因为后者是引用类型。