我遇到了写一个.ps1脚本的奇怪行为。我编写了一个带有两个参数的函数,但由于某种原因,第二个参数始终为null。
仔细观察后,我的两个参数似乎以某种方式折叠成第一个参数。
鉴于以下脚本,我原以为,一行输出显示...
function Foo($first, $second) {
echo $first
}
$x = "..."
$y = "why?"
Foo($x, $y)
但是当我运行这个脚本时,我得到了
...
why?
是否有一些PowerShell语法我不知道我不小心(误用)?
答案 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'
导致不必要的开销 我希望稍微澄清一下:)