Переменная область в PowerShell - PullRequest
59 голосов
/ 17 февраля 2012

В 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 ]

84 голосов
/ 03 марта 2013

Статья об областях применения PowerShell ( about_Scopes ) хороша, но слишком многословна, так что это цитата из моей статьи :

В общем, области применения PowerShellОбласти применения .NET.Это:

  • Глобальный общедоступный
  • Сценарий внутренний
  • Частный являетсяprivate
  • Local - текущий уровень стека
  • Пронумерованные области действия от 0..N, где каждый шаг до уровня стека (а 0Local)

Вот простой пример, который описывает использование и эффекты областей:

$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 как синтаксис только с namedОбласти, $ 0: тест всегда будет $ ноль.

69 голосов
/ 17 февраля 2012

Вы можете использовать модификаторы области действия или командлеты *-Variable.

Модификаторы области действия:

  • global, используемые для доступа / изменения всамая внешняя область (например, интерактивная оболочка)
  • script, используемая для доступа / изменения в области действия запущенного сценария (файл .ps1).Если сценарий не запущен, он работает как global.

(Для параметра -Scope командлетов *-Variable см. Справку.)

Например.во втором примере, чтобы напрямую изменить глобальный $array:

& {
  $global:array +="s"
  Write-Host $array
}

Для получения дополнительной информации см. раздел справки about_scopes .

15 голосов
/ 17 февраля 2012

Не только переменные.Когда это говорит «элемент», это означает переменные, функции, псевдонимы и psdrives.Все они имеют область действия.

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] для выполнения ваших обновлений или писать свой сценарий так, чтобы вы обновляли свойство объекта или ключ хеш-таблицыобъект или хеш-таблица в родительской области видимости.Это не создает новый объект в локальной области, оно изменяет объект в родительской области.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...