反转位置参数

Reversed Positional Parameters

我想为我正在编写的 PowerShell 脚本使用位置参数,但我希望参数从右到左输入(一个是必需的,一个是命名的)。这是它的外观示例:

command [-namedParams andTheirValues] [[param3] param2] param1

或分别针对每个用例:

command [-namedParams andTheirValues] param1
command [-namedParams andTheirValues] param2 param1
command [-namedParam andItsValue] param3 param2 param1

我试图将 [parameter(Position=n)] 与负索引一起使用(因为我真正想要的是根据参数的位置将参数绑定到末尾),但这没有用:

param (
    [String]$namedParam,
    [parameter(Position=-3)][String]$param3,
    [parameter(Position=-2)][String]$param2,
    [parameter(Mandatory=$True,Position=-1)][String]$param1
)

有什么想法吗?如果我需要,我将只处理代码中的参数,但我希望语法糖能为我做这件事。

有趣的问题……正如您所发现的,您不能使用负值来定义位置参数。我找到的最近的参考来自 about_Functions_Advanced_Parameters:

The value of the Position argument is specified as an integer. A position value of 0 represents the first position in the command, a position value of 1 represents the second position in the command, and so on.

这将是对缺乏负值的最好支持。文档可能有误,但正如您所试验的那样,它不起作用。

不过,我想我想出了一个简单的方法来处理这个问题。考虑以下包含命名参数和 "positional"ish 参数的函数。我们使用advanced function parameterValueFromRemainingArguments。请注意,我在 "positional" 周围的这个答案中多次使用引号,因为它们不是真正的位置参数。

function Das-Bagel{
    param (
        [String]$namedParam,
        [parameter(Mandatory=$true,
                      ValueFromRemainingArguments=$true)]
        [String[]]$remainingArguments
    )

    $param1 = $remainingArguments[-1]
    $param2 = $remainingArguments[-2]
    $param3 = $remainingArguments[-3]

    Get-Variable -Name param* | select name, value
}

它所做的只是显示 param# 变量及其值。话虽如此,让我们看看这两个不同命令的输出。首先只有一个 "positional" 参数。

PS C:\Users\Cameron> Das-Bagel -namedParam This First 

Name   Value
----   -----
param1 First
param2      
param3      

现在我们 运行 有 3 "positional" 个参数

PS C:\Users\Cameron> Das-Bagel -namedParam This First Second Third 

Name   Value 
----   ----- 
param1 Third 
param2 Second
param3 First 

第一个除了命名之外只有一个其他参数,因此它位于第一个位置。在第二个示例中,它成为第三个参数。不存在的参数将显示为其各自变量的空值。 PowerShell 在这方面很不错,因为它不会导致错误(默认情况下)。您需要在代码中考虑到这种可能性,但我想您已经涵盖了这一点。

此外,由于我们将其设为强制性,因此如果我们省略 "positional" 参数,函数调用将失败。