在powershell中无法合并

Mic*_*cah 97 powershell null-coalescing-operator

在PowerShell中是否存在空合并运算符?

我希望能够在powershell中执行这些c#命令:

var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
Run Code Online (Sandbox Code Playgroud)

Ste*_*enD 113

不需要Powershell社区扩展,您可以使用标准的Powershell if语句作为表达式:

variable = if (condition) { expr1 } else { expr2 }
Run Code Online (Sandbox Code Playgroud)

所以对你的第一个表达式的替换是:

var s = myval ?? "new value";
Run Code Online (Sandbox Code Playgroud)

成为以下之一(取决于偏好):

$s = if ($myval -eq $null) { "new value" } else { $myval }
$s = if ($myval -ne $null) { $myval } else { "new value" }
Run Code Online (Sandbox Code Playgroud)

或者取决于$ myval可能包含的内容,您可以使用:

$s = if ($myval) { $myval } else { "new value" }
Run Code Online (Sandbox Code Playgroud)

第二个表达式以类似的方式映射:

var x = myval == null ? "" : otherval;
Run Code Online (Sandbox Code Playgroud)

$x = if ($myval -eq $null) { "" } else { $otherval }
Run Code Online (Sandbox Code Playgroud)

现在公平地说,这些并不是非常活泼,并且没有像C#表格那样舒适的使用.

您也可以考虑将其包装在一个非常简单的函数中,以使事物更具可读性:

function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } }

$s = Coalesce $myval "new value"
Run Code Online (Sandbox Code Playgroud)

或者可能是,IfNull:

function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } }

$s = IfNull $myval "new value" $myval
$x = IfNull $myval "" $otherval
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,一个非常简单的函数可以为您提供相当多的语法自由.

更新:混合中需要考虑的一个额外选项是更通用的IsTrue函数:

function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } }

$x = IfTrue ($myval -eq $null) "" $otherval
Run Code Online (Sandbox Code Playgroud)

然后结合使用Powershell声明看起来有点像运算符的别名的能力,最终得到:

New-Alias "??" Coalesce

$s = ?? $myval "new value"

New-Alias "?:" IfTrue

$ans = ?: ($q -eq "meaning of life") 42 $otherval
Run Code Online (Sandbox Code Playgroud)

显然,这不是每个人的口味,但可能是你正在寻找的.

  • 与合并运算符唯一真正的等价物是使用if语句; 问题是任何其他方法都会评估所有操作数而不是短路."?? $ myval SomeReallyExpenisveFunction()"即使$ myval不为null也会调用该函数.我想可以使用scriptblock来延迟评估,但要注意脚本块不是闭包,事情开始变得笨重. (6认同)
  • 警告,powershell 怪癖,null 应该总是比较(笨拙地)将 null 放在第一位,即 `$null -ne $a` 现在找不到合适的参考,但这是长期的做法。 (2认同)

Zen*_*xer 83

是的,PowerShell确实有一个实际的空合并运算符,或者至少有一个能够执行此类行为的运算符.该运营商是-ne:

# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]

# Output:
alpha
Run Code Online (Sandbox Code Playgroud)

它比null合并运算符更通用,因为它创建了一个包含所有非空项的数组:

$items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false
$instances = $items -ne $null
[string]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() }))

# Result:
System.String, System.Int32, System.Int32, System.String, System.Object[],
System.Boolean, System.Boolean
Run Code Online (Sandbox Code Playgroud)

-eq 工作方式类似,这对于计算空条目很有用:

($null, 'a', $null -eq $null).Length

# Result:
2
Run Code Online (Sandbox Code Playgroud)

但无论如何,这是镜像C#??运算符的典型案例:

'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output
Run Code Online (Sandbox Code Playgroud)

说明

此解释基于匿名用户的编辑建议.谢谢,不管你是谁!

根据操作顺序,这按以下顺序进行:

  1. ,运算符创建值的阵列来进行测试.
  2. -ne操作者滤除从符合指定的值,所述阵列中的任何项目-在此情况下,空.结果是一个非空值数组,其顺序与步骤1中创建的数组的顺序相同.
  3. [0] 用于选择已过滤数组的第一个元素.

简化:

  1. 按优先顺序创建可能值的数组
  2. 排除数组中的所有空值
  3. 从结果数组中获取第一项

注意事项

与C#的空合并运算符不同,每个可能的表达式都将被计算,因为第一步是创建一个数组.

  • 啊,PowerShell的运营商优先权让我失望!我总是忘记逗号运算符`,`具有如此高的优先级.对于任何混淆它是如何工作的人,`($ null,'alpha',1 -ne $ null)[0]`与`(($ null,'alpha',1)-ne $ null相同[0] ]`.事实上,只有两个具有更高优先级的"破折号"运算符是`-split`和`-join`(和一元破折号?即``-4`或`-'56'`). (6认同)

Dun*_*can 14

这只是问题前半部分的答案的一半,所以四分之一答案,如果你愿意,但是有一个更简单的替代空合并运算符,前提是您要使用的默认值实际上是该类型的默认值:

string s = myval ?? "";
Run Code Online (Sandbox Code Playgroud)

可以用Powershell写成:

([string]myval)
Run Code Online (Sandbox Code Playgroud)

要么

int d = myval ?? 0;
Run Code Online (Sandbox Code Playgroud)

转换为Powershell:

([int]myval)
Run Code Online (Sandbox Code Playgroud)

在处理可能不存在的xml元素时,我发现第一个有用,如果它确实存在,可能会有不需要的空白:

$name = ([string]$row.td[0]).Trim()
Run Code Online (Sandbox Code Playgroud)

强制转换为字符串可以防止元素为空,并防止出现Trim()失败的风险.


EBG*_*een 9

如果您安装Powershell社区扩展模块,那么您可以使用:

?? 是Invoke-NullCoalescing的别名.

$s = ?? {$myval}  {"New Value"}
Run Code Online (Sandbox Code Playgroud)

?:是Invoke-Ternary的别名.

$x = ?: {$myval -eq $null} {""} {$otherval}
Run Code Online (Sandbox Code Playgroud)


Chr*_*oll 9

$null, $null, 3 | Select -First 1

回报

3


小智 5

最后,PowerShell 7 获得了空合并赋值运算符

PS > $null ?? "a"
a
PS > "x" ?? "y"
x
PS > $x = $null
PS > $x ??= "abc"
PS > $x
abc
PS > $x ??= "xyz"
PS > $x
abc
Run Code Online (Sandbox Code Playgroud)