首页 文章

PowerShell中的函数返回值

提问于
浏览
141

我开发了一个PowerShell函数,它执行了许多涉及配置SharePoint团队站点的操作 . 最后,我希望函数将配置站点的URL作为String返回,因此在我的函数结束时,我有以下代码:

$rs = $url.ToString();
return $rs;

调用此函数的代码如下所示:

$returnURL = MyFunction -param 1 ...

所以我期待一个String,但事实并非如此 . 相反,它是System.Management.Automation.PSMethod类型的对象 . 为什么它返回该类型而不是String类型?

8 回答

  • 213

    使用PowerShell 5,我们现在可以创建类 . 将函数更改为类不仅可以键入它,而且只返回它前面的对象 . 这是一个非常简单的例子 .

    class test_class{
        [int]return_what() {
            $a = "Hello World"
            return 808979
        }
    }
    $tc = New-Object -TypeName test_class
    $tc.return_what()
    

    如果这是一个函数,那么预期的输出就是

    Hello World
    808979
    

    但是作为一个类,唯一返回的是INT 808979.类是一种保证,它只返回声明的类型或void .

  • 4

    以下简单地返回4作为答案 . 替换字符串的add表达式时,它返回第一个字符串 .

    Function StartingMain {
      $a = 1 + 3
      $b = 2 + 5
      $c = 3 + 7
      Return $a
    }
    Function StartingEnd($b) {
      Write-Host $b
    }
    StartingEnd(StartingMain)
    

    这也可以用于阵列 . 以下示例将返回“Text 2”

    Function StartingMain {
      $a = ,@("Text 1","Text 2","Text 3")
      Return $a
    }
    Function StartingEnd($b) {
      Write-Host $b[1]
    }
    StartingEnd(StartingMain)
    

    请注意,您必须在函数本身下方调用函数,否则第一次运行它将返回一个错误,它不知道“StartingMain”是什么 .

    我希望它有所帮助 .

  • 3

    我传递一个简单的Hashtable对象和一个结果成员,以避免返回疯狂,因为我也想输出到控制台 . 它通过引用传递 .

    function sample-loop($returnObj) {
      for($i = 0; $i -lt 10; $i++) {
        write-host "loop counter: $i"
        $returnObj.result++
      }
    }
    
    function main-sample() {
      $countObj = @{ result = 0 }
      sample-loop -returnObj $countObj
      write-host "_____________"
      write-host "Total = " ($countObj.result)
    }
    
    main-sample
    

    您可以在我的GitHub project unpackTunes看到真实的示例用法

  • 37

    作为一种解决方法,我一直在返回数组中你从函数返回的最后一个对象...不是一个很好的解决方案,但它总比没有好:

    someFunction {
       $a = "hello"
       "Function is running"
       return $a
    }
    
    $b = someFunction
    $b = $b[($b.count - 1)]  # or 
    $b = $b[-1]              # simpler
    
  • 20

    卢克对这些情景中功能结果的描述似乎正确 . 只希望了解根本原因并且PowerShell产品团队会对该行为做些什么,似乎很常见并且花费了太多的调试时间 .

    为了解决这个问题,我一直在使用全局变量而不是返回并使用Function调用中的值 .

    这是使用全局变量的另一个线程:Setting a global PowerShell variable from a function where the global variable name is a variable passed to the function

  • 5

    PowerShell具有非常古怪的返回语义 - 至少从更传统的编程角度来看 . 有两个主要想法可以解决问题:

    • 捕获并返回所有输出

    • return关键字实际上只是表示逻辑出口点

    因此,以下两个脚本块将有效地完成相同的操作:

    $a = "Hello, World"
    return $a
    
    $a = "Hello, World"
    $a
    return
    

    第二个示例中的$ a变量在管道上保留为输出,如上所述,返回所有输出 . 实际上,在第二个示例中,您可以完全省略返回,并且您将获得相同的行为(当函数自然完成并退出时,将隐含返回) .

    如果没有更多的函数定义,我无法说明为什么要获得PSMethod对象 . 我的猜测是你可能有几行没有被捕获并被放置在输出管道上 .

    值得注意的是,您可能不需要那些分号 - 除非您在一行上嵌套多个表达式 .

    您可以在TechNet上的about_Return页面上阅读有关返回语义的更多信息,或者从PowerShell本身调用 help return 命令 .

  • 24

    没有看代码就很难说 . 确保您的函数不会返回多个对象,并且您捕获从其他调用中获得的任何结果 . 你得到了什么:

    @($returnURL).count
    

    无论如何,两个建议:

    将对象转换为字符串:

    ...
    return [string]$rs
    

    或者只是用双引号将其括起来,与上面相同但是更短以输入:

    ...
    return "$rs"
    
  • 4

    PowerShell的这一部分可能是最愚蠢的方面 . 在函数期间生成的任何无关输出都会污染结果,有时没有输出,然后在某些情况下除了计划的返回值之外还有其他一些计划外输出 .

    所以,我所做的是从原始函数调用中删除赋值,以便输出在屏幕上结束,然后逐步执行,直到我没有计划在调试器窗口中弹出的内容(使用PS ISE) .

    甚至像保留外部作用域中的变量之类的东西也会导致输出,比如 [boolean]$isEnabled ,除非你把它变成_461018,否则它会恼怒地吐出一个False .

    另一个好的是 $someCollection.Add("thing") ,这会吐出新的收藏计数 .

相关问题