可以将变量串在一起以清除它们吗?
Is it ok to string variables together to clear them?
因此,可以使用 Clear-Variable
cmdlet 清除变量,这与给它赋值 $null
.
是一样的
也可以使用环境变量的 Remove-Variable
cmdlet or the 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
的价值吗?
... a legitimate way of clearing variables
是的,像 $var1 = $var2 = $null
(以 2 变量为例)是 清除变量值的合法方法,前提是目标变量实际上是 defined 在 local(当前)范围内。
如果它们仅在 parent(祖先)范围内可见,您将无意中创建同名的 local 变量其值为 $null
- 参见 .
原则上同样适用于Clear-Variable var1, var2
,除了它会发出错误如果没有local 变量 $var1
和 $var2
已定义;此外,Clear-Variable
允许使用 -Scope
.
明确定位不同的范围
有限制,您还可以使用范围说明符(例如 $script:var
)将其他范围作为变量赋值的目标 - 参见 .
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 会尝试 convert $null
为锁定类型,该类型可以有两个结果:
转换成功,此时锁定类型的converted值为新值;例如,在 [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
并且给多个变量赋一个非空值:
如评论中所述,结果行为归结为是否分配了 value-type instance or a reference-type 实例[1]:
使用值类型实例,每个变量都有自己的值的独立副本。
# 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
使用引用类型实例,所有变量真正引用同一个对象。
# 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-type 语义,以提供更直观的字符串处理 - 参见 this answer.
New-Object
可以实例化任何一种类型:如果你给它一个值类型的名字,你会得到一个值类型的实例;给定引用类型的名称,您将获得一个引用类型实例。
但是,鉴于内置值类型可以用文字(例如,1
)或简单的强制转换([int]
)实例化,New-Object
更通常用于实例化引用类型。
[1] 给定类型或实例,您可以检查类型的 .IsValueType
属性 以确定它是否是值类型;例如,因为 [int]
(System.Int32
) 是一个值类型 [int].IsValueType
并且 (1).GetType().IsValueType
产生 $true
,而 [System.IO.FileInfo].IsValueType
是 $false
,因为后者是引用类型。
因此,可以使用 Clear-Variable
cmdlet 清除变量,这与给它赋值 $null
.
也可以使用环境变量的 Remove-Variable
cmdlet or the 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
的价值吗?
... a legitimate way of clearing variables
是的,像 $var1 = $var2 = $null
(以 2 变量为例)是 清除变量值的合法方法,前提是目标变量实际上是 defined 在 local(当前)范围内。
如果它们仅在 parent(祖先)范围内可见,您将无意中创建同名的 local 变量其值为 $null
- 参见
原则上同样适用于Clear-Variable var1, var2
,除了它会发出错误如果没有local 变量 $var1
和 $var2
已定义;此外,Clear-Variable
允许使用 -Scope
.
有限制,您还可以使用范围说明符(例如 $script:var
)将其他范围作为变量赋值的目标 - 参见
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 会尝试 convert $null
为锁定类型,该类型可以有两个结果:
转换成功,此时锁定类型的converted值为新值;例如,在
[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
并且给多个变量赋一个非空值:
如评论中所述,结果行为归结为是否分配了 value-type instance or a reference-type 实例[1]:
使用值类型实例,每个变量都有自己的值的独立副本。
# 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
使用引用类型实例,所有变量真正引用同一个对象。
# 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-type 语义,以提供更直观的字符串处理 - 参见 this answer.
New-Object
可以实例化任何一种类型:如果你给它一个值类型的名字,你会得到一个值类型的实例;给定引用类型的名称,您将获得一个引用类型实例。
但是,鉴于内置值类型可以用文字(例如,1
)或简单的强制转换([int]
)实例化,New-Object
更通常用于实例化引用类型。
[1] 给定类型或实例,您可以检查类型的 .IsValueType
属性 以确定它是否是值类型;例如,因为 [int]
(System.Int32
) 是一个值类型 [int].IsValueType
并且 (1).GetType().IsValueType
产生 $true
,而 [System.IO.FileInfo].IsValueType
是 $false
,因为后者是引用类型。