问题 Powershell'x或y'赋值


有几种语言可以提供默认或逻辑或分配机制:

a = b || c;
a = b or c
a="${b:-$c}"
a = b ? b : c;

到目前为止,我在Powershell Core中发现的唯一等价物是非常冗长:

$a = if ($b) { $b } else { $c }

在某些情况下必须成为

$a = if ($b -ne $null) { $b } else { $c }

有没有更好的选择[编辑:]不牺牲可读性?


6829
2017-07-24 22:10


起源

这是一篇带有示例函数的好文章。事实证明 = 成为支持三元和零合并的函数。 - TheIncorrigible1
有一个 GitHub上的功能请求 将此添加到PowerShell语言;请在那里听到你的声音。 - mklement0
@TheIncorrigible1:是的:有一个 相关功能请求添加三元条件 (Where-Object 被解析了 论据 模式,所以没有冲突 表达 模式)。 - mklement0
@kfsone:很棒的问题;旁白:为了可靠地测试 $null, $null 必须用作 LHS   - $null -ne $b  - 因为RHS操作数充当 过滤  与 数组值 PowerShell中的LHS(试试吧 'foo', 'bar' -ne $null)。 - mklement0
@ mklement0哦,TIL!更多的原因是有一个特定的运营商。 - kfsone


答案:


没有 || PowerShell任务中的短路运算符,没有任何与Perl相同的东西 // “定义 - 或”运算符 - 但你可以构造一个简单的 null coalesce 像这样模仿:

function ?? {
  param(
    [Parameter(Mandatory=$true,ValueFromRemainingArguments=$true,Position=0)]
    [psobject[]]$InputObject,

    [switch]$Truthy
  )

  foreach($object in $InputObject){
    if($Truthy -and $object){
      return $object
    }
    elseif($object -ne $null){
      return $object
    }
  }
}

然后使用像:

$a = ?? $b $c

或者,如果你想要返回任何已经评估过的东西 $true 就像你的第一个例子:

$a = ?? $b $c -Truthy

9
2017-07-24 22:31



这是一种勇敢的努力,但是,在一天结束时,除非它是 内置于语言中,它可能不会去任何地方 - 投票给后者 github.com/PowerShell/PowerShell/issues/3240 和 github.com/PowerShell/PowerShell/issues/3239 - mklement0
@ mathias-r-jessen很棒的答案,但大概是你说“内置没有这样的功能”?如果是这样,我可以用澄清编辑答案并接受它。 - kfsone
@kfsone修复:) - Mathias R. Jessen


所以减少这个的简单方法:

$a = if ($b -ne $null) { $b } else { $c }

将使用true和false只是一个或零的事实,可以像这样使用数组索引:

$a =  @($c, $b)[$b -ne $null]

4
2017-07-25 09:26



这是超级整洁,虽然我认为我在公关中将其标记为不可读。 - TheIncorrigible1
不幸的是,我不得不同意@TheIncorrigible1 - 这是让同事们学习Powershell的可靠方法:( - kfsone