Переменная область видимости в PowerShell
печальная вещь о PowerShell заключается в том, что функции и скриптовые блоки динамически ограничены.
но есть еще одна вещь, которая меня удивила, это то, что переменные ведут себя как копия при записи во внутренней области.
$array=@("g")
function foo()
{
$array += "h"
Write-Host $array
}
& {
$array +="s"
Write-Host $array
}
foo
Write-Host $array
выход:
g s
g h
g
что делает динамический обзор немного менее болезненным. Но как мне избежать копирования на запись?
3 ответа:
можно использовать модификаторы области или
*-Variable
командлетов.объем модификаторы:
global
используется для доступа/изменения во внешней области (например. интерактивная оболочка)script
используется при доступе / изменении в области запущенного скрипта (.ps1
file). Если скрипт не запущен, то работает какglobal
.(для
-Scope
параметр*-Variable
командлетов см. помощь.)например. во втором примере, чтобы непосредственно изменить глобальный
$array
:& { $global:array +="s" Write-Host $array }
дополнительные сведения см. В разделе справки в разделе about_scopes.
статья области действия PowerShell (в разделе about_scopes) приятно, но слишком многословно, так что это цитата из моего статьи:
В общем случае области PowerShell похожи на области .NET. Они таковы:
- глобальные общественная
- скрипт внутренний
- частная частный
- Local текущий стек уровень
- пронумерованных областей от 0..N где каждый шаг до уровня стека (и 0 является локальным)
вот простой пример, который описывает использование и эффекты областей:
$test = 'Global Scope' Function Foo { $test = 'Function Scope' Write-Host $Global:test # Global Scope Write-Host $Local:test # Function Scope Write-Host $test # Function Scope Write-Host (Get-Variable -Name test -ValueOnly -Scope 0) # Function Scope Write-Host (Get-Variable -Name test -ValueOnly -Scope 1) # Global Scope } Foo
Как вы можете видеть, вы можете использовать синтаксис $Global:test like только с именованными областями, $0: test всегда будет $null.
не только varibles. При этом говорит, что "товар" это означает, переменные, функции, псевдонимы и диски. Все они имеют объем.
LONG DESCRIPTION Windows PowerShell protects access to variables, aliases, functions, and Windows PowerShell drives (PSDrives) by limiting where they can be read and changed. By enforcing a few simple rules for scope, Windows PowerShell helps to ensure that you do not inadvertently change an item that should not be changed. The following are the basic rules of scope: - An item you include in a scope is visible in the scope in which it was created and in any child scope, unless you explicitly make it private. You can place variables, aliases, functions, or Windows PowerShell drives in one or more scopes. - An item that you created within a scope can be changed only in the scope in which it was created, unless you explicitly specify a different scope.проблема копирования при записи, которую вы видите, связана с тем, как Powershell обрабатывает массивы. Добавив к этому массиву фактически уничтожает исходный массив и создает новый. Поскольку он был создан в этой области, он уничтожается при выходе функции или блока сценария и удалении области.
вы можете прямо охвата переменные при их обновлении, или вы можете использовать объекты [ref] для выполнения обновлений, или написать сценарий, чтобы вы обновляли свойство объекта или ключ хэш-таблицы объекта или хэш-таблицы в родительской области. Это не создает новый объект в локальной области, он изменяет объект в родительской области.