The weird 'return' in powershell

Powershell 對於初學者來說,怪異之處良多,一個function的返回值可能並不都是你想要的,直接上代碼

function isThere(){
    $arr = 1..10
    foreach($item in $arr){
        if($item -eq 5){
            return $true
         }
    }
    return $false
}
function isThere1(){
    $arr = 1..10
    $arr | ForEach-Object{
         if($_ -eq 5){
            return $true
         }
    }
    return $false
}
isThere   # 返回值:$true
isThere1  # 返回值:[$true,$false]

問題一: Powershell會返回好多值

與其他編程語言java,c#,javascript等不同,powershell作爲一個bash腳本,其命令可能會有返回值,比如new-item在命令行內就會返回新創建的對象,在ps1腳本內也會返回,但是在function函數內,會將結果組成一個collection或者list,一起返回。

MDN也是如此的解釋:

In PowerShell, values can be returned even if the Return keyword is not used. The results of each statement are returned.
在Powrshell裏,不管用不用Return關鍵字,值都會被返回。

function calc($x,$y){
    $x;
    $sum = $x+$y
    New-Item -Path . -Name "sum.log" -ItemType "file" -Value $sum
    return $sum
}

舉個例子,上邊是一個求和的函數,求和的過程中需要把和存到一個sum.log的文件中,並返回和值。但是return $sum 並不會是你想要的兩個的和值,因爲new-item會有生成文件的結果也一併返回,所以,而是一個PSarray對象,裏邊第一項會是new-item的結果,第二項爲你的和值。

問題二: Return只能跳出當前的作用域

最上邊例子,爲什麼用過pipeline的foreach-object會返回[true,false]呢,因爲從問題一可以知道,Powershell的function會收集所有的返回值來一起return。而return true以後,又執行了 return false,所以才形成了這樣的結果,那問題就來了,爲什麼return沒跳出整個function返回第一個true呢?

再次祭出文檔

SHORT DESCRIPTION
Exits the current scope, which can be a function, script, or script block.
Return會跳出當前的作用域,包括函數,腳本,塊級腳本

而不巧的是foreach-object剛好就是script block。所以return只會跳出foreach-object,後邊的return false仍然會執行,而foreach並不是上述的三者之一,所以return會跳出整個function,並返回我想要的true。
這裏寫圖片描述

歡迎批評交流

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章