...清除变量的合法方式
是的,类似 $var1 = $var2 = $null(仅以 2 个变量为例)是清除变量值的合法方式,前提是目标变量实际上是在本地(当前)范围内定义的。
如果它们仅在 父(祖先)范围内可见),您将无意中创建 local 同名变量,其值为 $null - 请参阅this answer.
这同样适用于 Clear-Variable var1, var2 原则上,除了如果没有 local 变量 @987654330 它会发出 error @ 和 $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有以下优势:
- 它更简洁,速度也更快(无需调用 cmdlet)。
- 它可用于隐式创建具有
$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 并为多个变量分配一个非空值:
如 cmets 中所述,结果行为归结为分配的是 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,因为后者是引用类型。 p>