简短说明
介绍如何创建和使用引用类型变量。
详细说明
可以通过引用或按值将变量传递给函数。
按值传递变量时,将传递数据的副本。 通过引用传递变量 [ref] 创建的,它是 [System.Management.Automation.PSReference] 类型的类型加速器。
[ref] 的主要目的是通过引用标记为 ref、out或 in的 .NET 方法参数来传递 PowerShell 变量。 还可以定义自己的 PowerShell 函数,该函数采用 [ref] 类型参数。 在此用法中,[ref] 应用于 变量,生成的 [ref] 实例可用于间接修改该变量的值。
在以下示例中,该函数会更改传递给它的变量的值。 在 PowerShell 中,整数是值类型,因此它们按值传递。
因此,$var 的值在函数范围之外保持不变。
Function Test($Data)
{
$Data = 3
}
$var = 10
Test -Data $var
$var
10
在以下示例中,会将包含 Hashtable 的变量传递给函数。
通过引用传递变量时,该函数可以更改数据,并在函数执行后保留该更改。
Function Test($Data)
{
$Data.Test = "New Text"
}
$var = @{}
Test -Data $var
$var
Name Value
---- -----
Test New Text
该函数添加了一个新的键值对,该对将保留在函数范围之外。
编写函数以接受引用参数
可以将函数编码为参数作为引用,而不考虑传递的数据类型。 这要求将参数类型指定为 [ref]。
使用引用时,必须使用 Value 类型的 [ref] 属性来访问数据。
function Test {
param([ref]$Data)
$Data.Value = 3
}
若要将变量传递给需要引用的参数,必须键入将变量强制转换为引用。
重要
括号和圆括号都是必需的。
$var = 10
Test -Data ([ref]$var)
$var
3
传递对 .NET 方法的引用
某些 .NET 方法可能需要将变量作为引用传递。 当方法的定义对参数使用关键字 in、 out 或 ref 时,它需要引用。
[int] | Get-Member -Static -Name TryParse
Name MemberType Definition
---- ---------- ----------
TryParse Method static bool TryParse(string s, [ref] int result)
TryParse 方法尝试将字符串分析为整数。 如果方法成功,它将返回 $true,结果存储在通过引用传递的变量中。
PS> $number = 0
PS> [int]::TryParse("15", ([ref]$number))
True
PS> $number
15
引用和范围
引用允许在子作用域内更改父范围内的变量的值。
# Create a value type variable.
$i = 0
# Create a reference type variable.
$iRef = [ref]0
# Invoke a scriptblock to attempt to change both values.
&{$i++;$iRef.Value++}
# Output the results.
"`$i = $i;`$iRef = $($iRef.Value)"
$i = 0;$iRef = 1
仅更改引用类型的变量。
用作 [ref] 常规用途对象持有者
你也可以将 [ref] 用作通用的对象容器。 在此用法中,[ref] 应用于 值 而不是变量。 通常,该值是
例如,可以使用脚本块参数值来计算 cmdlet Rename-Item 参数的值。
Rename-Item cmdlet 允许通过管道将相应项传送给它。 该命令运行传递给管道中每个项的 NewName 的 scriptblock。 脚本块在子作用域中运行。 直接修改调用方作用域中的变量将无济于事,并且不能在此上下文中将参数传递给脚本块。
在此示例中,传递给 NewName 参数的 scriptblock 递增管道中每个项的值 $iRef 。 Scriptblock 通过向文件名开头添加一个数字来创建一个新名称。
$iRef = [ref] 0
Get-ChildItem -File $setPath |
Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name }
和[ref][System.Management.Automation.PSReference]
引用类型变量是使用 [ref] 类型加速器创建的,或通过直接指定 [System.Management.Automation.PSReference] 类型来创建。 尽管 [ref] 是 [System.Management.Automation.PSReference]的类型加速器,但它们的行为也不同。
- 使用
[ref]转换变量时,PowerShell 将创建一个引用对象,其中包含对变量原始实例的引用。 - 使用
[System.Management.Automation.PSReference]转换变量时,PowerShell 将创建一个引用对象,其中包含变量的副本,而不是对原始实例的引用。
例如,以下脚本创建一个变量 $x 和两个引用对象。
PS> $int = 1
PS> $aRef = [ref] $int
PS> $bRef = [System.Management.Automation.PSReference] $int
PS> $int
1
PS> $aRef, $bRef
Value
-----
1
1
此时,两个引用对象的值都与 $int相同。 通过将不同的值添加到引用对象,可以看到使用 $aRef创建的 [ref]是对 $int的原始实例的引用。
使用 $bRef创建的 [System.Management.Automation.PSReference]是变量的副本。
PS> $aRef.Value+=2
PS> $bRef.Value+=5
PS> $int
3
PS> $aRef, $bRef
Value
-----
3
6