【问题标题】:Variable Scopes Within PowerShell Nested FunctionsPowerShell 嵌套函数中的变量范围
【发布时间】:2015-07-02 03:12:00
【问题描述】:

我从一家大型/信誉良好的公司获得了这个广泛的 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
}

【问题讨论】:

    标签: powershell scope nested-function


    【解决方案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
    

    【讨论】:

    • 我觉得您的回答非常棒,非常感谢。但是,关于你的说法,“当子函数执行完毕后,变量将恢复到子函数被调用之前的原始值”,我有一些疑问。我认为嵌套范围内的变量将在本地新生成,仅具有与父范围中具有相同名称的变量相同的值。父作用域内的变量在嵌套作用域内被操纵并返回初始值的真正机制是什么?我认为这是一个浪费的过程。
    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 2011-07-10
    • 2016-09-25
    • 2012-06-24
    • 1970-01-01
    • 2019-08-21
    • 2016-02-19
    • 2019-04-30
    相关资源
    最近更新 更多