将变量串在一起以清除它们是否可以?

时间:2019-10-26 09:25:54

标签: powershell variable-assignment

因此,可以使用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吗?

1 个答案:

答案 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 具有以下优势:

  • 它更简洁,也更快(不需要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] $null0

    [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,因为后者是引用类型。