两个功能参数合并为一个?

时间:2014-07-10 22:20:38

标签: function powershell parameters

我遇到了写一个.ps1脚本的奇怪行为。我编写了一个带有两个参数的函数,但由于某种原因,第二个参数始终为null。

仔细观察后,我的两个参数似乎以某种方式折叠成第一个参数。

鉴于以下脚本,我原以为,一行输出显示...

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

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

Foo($x, $y)

但是当我运行这个脚本时,我得到了

...
why?

是否有一些PowerShell语法我不知道我不小心(误用)?

3 个答案:

答案 0 :(得分:6)

不要在你的参数周围使用parens,也不要使用逗号分隔参数。像调用任何其他PowerShell命令一样调用您的函数 - 使用空格分隔的参数,例如:

foo $x $y

当你把parens放在($ 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

答案 1 :(得分: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 >

答案 2 :(得分: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'

导致不必要的开销 我希望稍微澄清一下:)