【问题标题】:Is there a short circuit 'or' that returns the first 'true' value?是否存在返回第一个“真”值的短路“或”?
【发布时间】:2015-08-16 05:24:33
【问题描述】:

方案有一个短路or 将返回第一个非假值:

> (or 10 20 30)
10
> (or #f 20 30)
20
> (or #f)
#f

在需要之前它不会评估它的参数。

PowerShell 中是否已经存在类似的东西?

这是它的近似值:

function or ()
{
    foreach ($arg in $args) {
        $val = & $arg; if ($val) { $val; break }
    }
}

例子:

PS C:\> or { 10 } { 20 } { 30 }
10

例子:

PS C:\> $abc = $null

PS C:\> or { $abc } { 123 }
123

PS C:\> $abc = 456

PS C:\> or { $abc } { 123 }
456

【问题讨论】:

标签: powershell short-circuiting


【解决方案1】:

你可以这样做:

10, $false, 20 | ? { $_ -ne $false } | select -First 1

结果是输入列表中不是$false$null 的第一个值。由于 $null 是 PowerShell treats as $false 比较的值之一,因此上面的值应该可以满足您的要求。

【讨论】:

  • 这是迄今为止最好的答案,也是最有用的。
【解决方案2】:

据我所知,没有这样的内置功能。我认为您的功能看起来不错。

采用流水线输入可能更惯用:

function or
{
    foreach ($x in $input) {
        $val = & $x; if ($val) { $val; break }
    }
}

例子:

PS > $abc = $null
PS > { $abc },{ 123 } | or
123    
PS > $abc = 456
PS > { $abc },{ 123 } | or
456

【讨论】:

    【解决方案3】:

    您正试图通过您的函数使 PowerShell 使用类似于 Scheme 的语法。不要这样做。编写惯用的 PowerShell。试图强迫一种语言看起来像另一种语言只会让你自己变得更难,给错误引入很多空间,并且会混淆 %$^%&^*(你走后的代码。

    PowerShell 确实出现短路。将此代码放入 ISE 并在每个函数的 write-output 行设置断点,然后启动调试器 (F5):

    function first () {
        write-output "first"
    }
    
    function second() {
        write-output "second"
    }
    
    $true -or $(first) -or $(second);
    $false -or $(first) -or $(second);
    $false -or $(second) -or $(first);   
    

    $true 计算结果为真(显然),因此它不会尝试处理超出该点的表达式。当倒数第二行处理时,只处理first 中的断点。最后一行处理时,只命中second()中的断点。

    【讨论】:

    • 你好alroc。 -or 运算符不返回第一个非 false 表达式的值。它总是返回$true$false
    • 这可以追溯到您尝试编写伪装成 Scheme 的 PowerShell,而不是编写惯用的 PowerShell。
    【解决方案4】:

    只要给函数起个好听的名字,我认为创建这样的函数是完全地道的 Powershell。我将对 OP 的实现进行的一项调整是使传入脚本块成为可选:

    function Select-FirstValue {
        $args |
            foreach { if ($_ -is [scriptblock]) { & $_ } else { $_ } } |
            where { $_ } |
            select -First 1
    }
    

    然后调用者只需要在可能有副作用或性能成本高的参数周围添加{ }括号。

    我正在使用这样的函数作为从配置文件中为params 提供默认值的简单方法。它看起来像:

    function Do-Something {
        param([string]$Arg1)
    
        $Arg1 = Select-FirstValue $Arg1 { Get-ConfigValue 'arg1' } 'default arg1 val'
    
        [...]
    }
    

    这样,只有在用户没有传入参数时才会尝试读取配置文件。

    【讨论】:

      猜你喜欢
      • 2010-12-05
      • 2022-07-13
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 2021-12-10
      • 1970-01-01
      • 2017-12-11
      • 2023-03-30
      相关资源
      最近更新 更多