在powershell中,您可以使用以下方法创建函数function name {commands}并使这些函数接受参数:
function myFunction {
param($var1, $var2)
}
Run Code Online (Sandbox Code Playgroud)
但你也可以用
function myFunction($var1, $var2) {}
Run Code Online (Sandbox Code Playgroud)
他们会是一样的。
例如,如果我创建了一个函数func1:
function func1 {
param($var1, $var2)
echo "$var1 $var2"
}
Run Code Online (Sandbox Code Playgroud)
我会通过使用func1 1 2where $var1will be equal to1和$var2will be equal to 来调用它2。
输入:
PS C:\Users\Neko> func1 1 2
Run Code Online (Sandbox Code Playgroud)
输出:
1 2
Run Code Online (Sandbox Code Playgroud)
但是,如果我做同样的事情,而是使用另一种将参数传递给函数的方法:
function func2($var1, $var2) {
echo "$var1 $var2"
}
Run Code Online (Sandbox Code Playgroud)
我也会以完全相同的方式调用它,通过使用func2 1 2where$var1将等于1和$var2等于2前一个函数来调用它。
输入:
PS C:\Users\Neko> func2 1 2
Run Code Online (Sandbox Code Playgroud)
输出:
1 2
Run Code Online (Sandbox Code Playgroud)
因此,函数的两个再现之间的一切似乎都相同且不变,所以我的问题是,将参数传递给函数的两种方法之间是否存在差异,或者它们实际上是否相同?即使它是最细微的细节,或者只是解析差异,我也想知道两者在功能上的任何差异,因为 param 也有其他用途。
UPDATE:的参数,你可以在做param喜欢[parameter(Mandatory=$true, ValueFromPipeline=$true)]和[String[]]是不是唯一的PARAM。您还可以通过执行以下操作在另一个“非参数”示例中完成此操作:
function func2(
[parameter(Mandatory=$true, ValueFromPipeline=$true, etc)]
[String[]]
$var1, $var2
) {
echo "$var1 $var2"
}
Run Code Online (Sandbox Code Playgroud)
为了补充7cc 的有用答案:
虽然在定义函数的参数时这两种语法形式大多可以互换,但只有块语法在以下情况下有效:param(...)
如果您想使用[CmdletBinding()]属性使您的函数或脚本成为高级函数或脚本。[1]
如果您正在编写脚本文件( *.ps1) 或脚本块( { ... }):为它们声明参数的唯一方法是param(...)在开头放置一个块。
因此,您可以选择始终使用param(...)块语法,以确保函数和脚本参数定义之间的一致性。
如果使用[CmdletBinding(...)]) 属性,它必须直接位于param(...)块之前。
至于:
我会用
func1(1)(2)
不,你会这样称呼它:
func1 1 2
Run Code Online (Sandbox Code Playgroud)
也就是说,PowerShell 函数的调用方式类似于shell 命令:不带括号,以空格分隔;虽然您的调用恰好也有效,但使用(...)围绕参数可以改变它们的解释:
没有封闭(...)的参数在参数模式下被解析,其中,值得注意的是,字符串不需要被引用
与封闭的(...), 在表达式模式下解析,其中字符串确实需要引用。
有关更多信息,请参阅此答案。
[1] 虽然您可以将[CmdletBinding(...)]属性放在带有function Foo (...) { ... }语法的括号内而不会引起错误,但这样做实际上被忽略了。另外,在没有(有效的)显式 [CmdletBinding(...)]属性的情况下,无论使用哪种语法,如果您碰巧用[Parameter()]属性装饰至少一个参数,您将获得高级函数的默认行为(例如,支持自动通用参数,例如-Verbose) ,因为使用[Parameter()] 隐式使函数成为高级函数(就像一个[CmdletBinding()]属性 - 没有显式属性值 - 有效)。但是,如果您需要显式[CmdletBinding(...)]属性,以便选择非默认高级功能行为,通过属性值,例如PositionalBinding=$falseor SupportsShouldProcess=$true,使用param(...)块是您唯一的选择。
一件事是该CmdletBinding属性需要Param
function Echo-Confirm
{
# Here
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
Param ($val=1)
if ($PSCmdlet.ShouldProcess($val) -eq $true) {
Write-Output "Confirmed $val"
}
}
Run Code Online (Sandbox Code Playgroud)
在此评论后编辑
语法很好,但CmdletBinding没有效果
Function foo (
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
[Parameter()]$val=1
) {
# never confirm
if ($PSCmdlet.ShouldProcess($val) -eq $true) {
Write-Output "always here"
}
else {
Write-Output "never here"
}
}
foo -Confirm
# throws an error
foo: A parameter cannot be found that matches parameter name 'confirm'.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |