Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Краткое описание
Описывает создание и использование переменной ссылочного типа.
Длинное описание
Переменные можно передавать в функции по ссылке или по значению. При передаче переменной по значениюпередается копия данных. При передаче переменной по ссылкевы передаете ссылку на исходное значение.
Это позволяет функции изменять значение переменной, передаваемой в нее. Ссылочные типы создаются с помощью [ref], который является акселератором типов для типа [System.Management.Automation.PSReference].
Основной целью [ref] является включение передачи переменных PowerShell путем ссылки на параметры метода .NET, помеченные как ref, outили in. Вы также можете определить собственную функцию PowerShell, которая принимает параметры типа [ref]. В этом случае [ref] применяется к переменной , а результирующий экземпляр [ref] можно использовать для косвенного изменения значения этой переменной.
В следующем примере функция изменяет значение переменной, переданной в нее. В PowerShell целые числа являются типами значений, поэтому они передаются по значению.
Таким образом, значение $var не изменяется вне области функции.
Function Test($Data)
{
$Data = 3
}
$var = 10
Test -Data $var
$var
10
В следующем примере переменная, содержащая Hashtable, передается функции.
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] применяется к значению вместо переменной. Как правило, значение — это экземпляр типа значения , например, число. В большинстве сценариев вместо нее можно использовать обычную переменную или параметр. Однако этот метод полезен в сценариях, когда передача явного держателя значений не требуется (для краткости) или невозможна, например в значениях параметров блока скрипта.
Например, можно использовать значения параметров блока скрипта для вычисления значения параметра NewName командлета Rename-Item. Командлет Rename-Item позволяет передавать в него элементы. Команда запускает блок скрипта, переданный в NewName для каждого элемента в конвейере. Блок скрипта выполняется в дочерней области. Изменение переменной в области вызывающего объекта напрямую не поможет, и вы не можете передать аргументы в блок скриптов в этом контексте.
В этом примере блок скрипта, переданный параметру NewName , увеличивает значение $iRef каждого элемента в конвейере. Блок скрипта создает новое имя, добавив число в начало имени файла.
$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
См. также
PowerShell