2014-07-10 59 views
0

我遇到了寫一個.ps1腳本的奇怪行爲。我寫了一個帶有兩個參數的函數,但由於某種原因,第二個參數始終爲空。兩個函數參數合併爲一個?

經過仔細檢查,似乎我的兩個參數以某種方式被摺疊到第一個參數中。

給出下面的腳本,我本來期望,一行輸出顯示...

function Foo($first, $second) { 
    echo $first 
} 

$x = "..." 
$y = "why?" 

Foo($x, $y) 

但是當我運行該腳本,我得到

... 
why? 

有一些PowerShell的語法我不不知道我是不小心(錯誤)使用?

回答

6

不要在你的論據括號和不使用逗號分隔參數。調用你的函數,就像你任何其他PowerShell命令 - 用空格隔開的參數,例如:

foo $x $y 

當你把周圍的括號($ X,$ y)的PowerShell的傳遞,作爲一個單一的表達/參數,在這種情況下,一個包含兩個項目的數組作爲函數的第一個參數($ x)。您可以使用Strict-Mode -Version Latest提醒你,當你做到這一點例如爲:

114> function foo($x,$y){} 
115> foo(3,4) 
116> Set-StrictMode -Version latest 
117> foo(3,4) 
The function or command was called as if it were a method. Parameters should be separated by 
spaces. For information about parameters, see the about_Parameters Help topic. 
At line:1 char:1 
+ foo(3,4) 
+ ~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : StrictModeFunctionCallWithParens 
2

是否有一些PowerShell語法...我意外(錯誤)使用?

是的,你沒有正確地調用你的功能。在PowerShell中,函數調用而不是使用括號或用逗號分隔它們的參數。

相反,你會打電話Foo像這樣:

Foo $x $y 

請參見下面的演示:

PS > function Foo($first, $second) { 
>>  echo $first 
>> } 
>> 
PS > $x = "..." 
PS > $y = "why?" 
PS > Foo $x $y 
... 
PS > 
PS > function Foo($first, $second) { 
>>  echo "$first and $second" 
>> } 
>> 
PS > Foo $x $y 
... and why? 
PS > 

如果你想知道,您目前的代碼有PowerShell的解釋($x, $y)作爲Foo的單個參數:一個兩項數組。因此,這個數組$first$null分配給$second

PS > function Foo($first, $second) { 
>>  echo "Type of `$first: $($first.Gettype())" 
>>  echo "`$second is `$null: $($second -eq $null)" 
>> } 
>> 
PS > $x = "..." 
PS > $y = "why?" 
PS > Foo($x, $y) 
Type of $first: System.Object[] 
$second is $null: True  
PS > 
+0

對不起,這個意外的編輯。我討厭如何隨機似乎重新排列答案。 –

1

的「」使用不同的PowerShell中比在其他編程語言。這是數組構造函數。

(1,2,3).GetType()  # System.Object[] 
(,'element').GetType() # System.Object[] 

因爲你還沒有指定你的參數的數據類型PowerShell的假設它在處理普通的舊System.Objects(所有類的父類)。然後它接受數組並將其分配給第一個輸入參數,因爲它是該行中唯一的參數。它可以這樣做,因爲一個數組通過擴展也是一個System.Object。

另外,建議不要老synthax定義功能了:

function foo ($first, $second) {} 

在寫這一點,PowerShell的解釋會在內部轉換成一個先進的功能,這一點:

function foo { 
    PARAM( 
     [Parameter(Position=1)] 
     [object]$first, 
     [Parameter(Position=2)] 
     [object]$second 
    ) 
    BEGIN { <# Do stuff here #> } 
    PROCESS { <# Do stuff here #> } 
    END { <# Do stuff here #> } 
} 

foo -first 'first' -second 'second' 
foo 'first' 'second' 

造成不必要的開銷。
我希望清除一點:)