Области Переменных Внутри Вложенных Функций PowerShell
Мне дали этот обширный сценарий PowerShell от крупной/авторитетной корпорации, который должен был работать безупречно. Ну, это не так.
Скрипт состоит из множества вложенных функций с множеством переменных, передаваемых в основную родительскую функцию, а затем во все ее дочерние функции. Дети, которые используют и изменяют все эти переменные.
Почему все эти переменные не содержат правильных данных?
Вот структура, о которой я говорю:
f1 {
f2 {
v #prints 0
v = 1
f3
}
f3 {
v #prints 1
v = 2
}
v = 0
f2
v #should print 2 but prints 0
}
1 ответ:
Внутри вложенных функций все дочерние функции имеют доступ ко всем переменным родительских функций. Любые изменения переменных видны в локальной области текущей функции и всех вложенных дочерних функций, вызываемых впоследствии. Когда дочерняя функция завершит выполнение, переменные вернутся к исходным значениям до вызова дочерней функции.
Чтобы применить изменения переменной во всех областях вложенных функций, область действия переменной тип должен быть изменен на
AllScope
:Set-Variable -Name varName -Option AllScope
Таким образом, независимо от того, на каком уровне во вложенных функциях изменяется переменная, изменение сохраняется даже после завершения дочерней функции, и родитель увидит новое обновленное значение.
Нормальное поведение областей переменных внутри вложенных функций:
function f1 ($f1v1 , $f1v2 ) { function f2 () { $f2v = 2 $f1v1 = $f2v #local modification visible within this scope and to all its children f3 "f2 -> f1v2 -- " + $f1v2 #f3's change is not visible here } function f3 () { "f3 -> f1v1 -- " + $f1v1 #value reflects the change from f2 $f3v = 3 $f1v2 = $f3v #local assignment will not be visible to f2 "f3 -> f1v2 -- " + $f1v2 } f2 "f1 -> f1v1 -- " + $f1v1 #the changes from f2 are not visible "f1 -> f1v2 -- " + $f1v2 #the changes from f3 are not visible } f1 1 0
Распечатка:
f3 -> f1v1 -- 2 f3 -> f1v2 -- 3 f2 -> f1v2 -- 0 f1 -> f1v1 -- 1 f1 -> f1v2 -- 0
Вложенные функции с переменными
AllScope
:function f1($f1v1, $f1v2) { Set-Variable -Name f1v1,f1v2 -Option AllScope function f2() { $f2v = 2 $f1v1 = $f2v #modification visible throughout all nested functions f3 "f2 -> f1v2 -- " + $f1v2 #f3's change is visible here } function f3() { "f3 -> f1v1 -- " + $f1v1 #value reflects the change from f2 $f3v = 3 $f1v2 = $f3v #assignment visible throughout all nested functions "f3 -> f1v2 -- " + $f1v2 } f2 "f1 -> f1v1 -- " + $f1v1 #reflects the changes from f2 "f1 -> f1v2 -- " + $f1v2 #reflects the changes from f3 } f1 1 0
Распечатка:
f3 -> f1v1 -- 2 f3 -> f1v2 -- 3 f2 -> f1v2 -- 3 f1 -> f1v1 -- 2 f1 -> f1v2 -- 3