据我所知,PowerShell似乎没有所谓的三元操作符的内置表达式。
例如,在支持三元操作符的C语言中,我可以写出以下代码:
<condition> ? <condition-is-true> : <condition-is-false>;
如果PowerShell中真的不存在这个功能,那么实现同样的结果最好的方式是什么(即易于阅读和维护)?
据我所知,PowerShell似乎没有所谓的三元操作符的内置表达式。
例如,在支持三元操作符的C语言中,我可以写出以下代码:
<condition> ? <condition-is-true> : <condition-is-false>;
$result = If ($condition) {"true"} Else {"false"}
如果要将其用作表达式而非仅仅是赋值,需使用 $()
将其包裹起来,例如:
write-host $(If ($condition) {"true"} Else {"false"})
$()
包装器强制将语句作为表达式进行求值,从而返回真值或假值,就像三元运算符一样。据我所知,这是在 PowerShell 中最接近的实现方式。 - KeithSPS C:\Users\js> 0 ? 'yes' : 'no'
no
PS C:\Users\js> 1 ? 'yes' : 'no'
yes
我能想到的最接近模拟它的PowerShell结构是:
@({'condition is false'},{'condition is true'})[$condition]
({true}, {false})[!$condition]
更好一些:a)真和假的部分遵循传统顺序;b)$condition
不必只是0或1或$false、$true。运算符!
会根据需要将其转换。也就是说,$condition
可以是任何值,比如42:!42 ~ $false ~ 0 ~ 第一个表达式。 - Roman Kuzmin尝试使用PowerShell的切换语句作为替代方案,特别是用于变量赋值-多行但易读。
例如,
$WinVer = switch ( Test-Path -Path "$Env:windir\SysWOW64" ) {
$true { "64-bit" }
$false { "32-bit" }
}
"This version of Windows is $WinVer"
?:
操作符:set-alias ?: Invoke-Ternary -Option AllScope -Description "PSCX filter alias"
filter Invoke-Ternary ([scriptblock]$decider, [scriptblock]$ifTrue, [scriptblock]$ifFalse)
{
if (&$decider) {
&$ifTrue
} else {
&$ifFalse
}
}
就像这样使用:
$total = ($quantity * $price ) * (?: {$quantity -le 10} {.9} {.75})
?:
被评估,它将需要对参数进行评估。如果没有脚本块,它将具有类似的用法,例如(?: ($quantity -le 10) {.9} {.75})
。 - user28647401 -gt 2 ? "Yes" : "No"
# Returns "No"
1 -gt 2 ? 'Yes' : $null
# Get a $null response for false-y return value
$null
。 - user189198# ---------------------------------------------------------------------------
# Name: Invoke-Assignment
# Alias: =
# Author: Garrett Serack (@FearTheCowboy)
# Desc: Enables expressions like the C# operators:
# Ternary:
# <condition> ? <trueresult> : <falseresult>
# e.g.
# status = (age > 50) ? "old" : "young";
# Null-Coalescing
# <value> ?? <value-if-value-is-null>
# e.g.
# name = GetName() ?? "No Name";
#
# Ternary Usage:
# $status == ($age > 50) ? "old" : "young"
#
# Null Coalescing Usage:
# $name = (get-name) ? "No Name"
# ---------------------------------------------------------------------------
# returns the evaluated value of the parameter passed in,
# executing it, if it is a scriptblock
function eval($item) {
if( $item -ne $null ) {
if( $item -is "ScriptBlock" ) {
return & $item
}
return $item
}
return $null
}
# an extended assignment function; implements logic for Ternarys and Null-Coalescing expressions
function Invoke-Assignment {
if( $args ) {
# ternary
if ($p = [array]::IndexOf($args,'?' )+1) {
if (eval($args[0])) {
return eval($args[$p])
}
return eval($args[([array]::IndexOf($args,':',$p))+1])
}
# null-coalescing
if ($p = ([array]::IndexOf($args,'??',$p)+1)) {
if ($result = eval($args[0])) {
return $result
}
return eval($args[$p])
}
# neither ternary or null-coalescing, just a value
return eval($args[0])
}
return $null
}
# alias the function to the equals sign (which doesn't impede the normal use of = )
set-alias = Invoke-Assignment -Option AllScope -Description "FearTheCowboy's Invoke-Assignment."
$message == ($age > 50) ? "Old Man" :"Young Dude"
=
作为别名,因为在C#和许多其他语言中用于相等性检查的是==
。在PowerShell中拥有一些C#经验是非常普遍的,这使得结果代码有点令人困惑。:
可能是一个更好的别名。与变量赋值=:
一起使用可能会让某人想起Pascal中使用的赋值,但在VB.NET和C#中没有任何直接等价物(据我所知)。 - nohwnd:
或 ~
或者其他你喜欢的。:Dset-alias : Invoke-Assignment -Option AllScope -Description "FearTheCowboy's Invoke-Assignment."
$message =: ($age > 50) ? "老头子" :"年轻小伙子"
$message =: $foo ?? "foo 为空"
- Garrett Serack由于三目运算符通常用于赋值操作,因此它应该返回一个值。以下是实现该功能的方式:
$var=@("value if false","value if true")[[byte](condition)]
有些愚蠢,但却起作用。此外,这种构造可以用于快速将整数转换为另一个值,只需添加数组元素并指定返回基于0的非负值的表达式即可。
[Condition] ? (output if True) : (output if False)
示例 01
$a = 5; $b = 6
($a -gt $b) ? "True" : "False"
输出
False
例子 02
($a -gt $b) ? ("$a is greater than $b") : ("$a is less than $b")
输出
5 is less than 6
更多信息https://www.tutorialspoint.com/how-ternary-operator-in-powershell-works
(此链接为介绍PowerShell中三元运算符的文章)Invoke-Ternary
Invoke-TernaryAsPipe
Invoke-NullCoalescing
NullCoalescingAsPipe
Set-Alias :?: Pscx\Invoke-Ternary -Description "PSCX alias"
Set-Alias ?: Pscx\Invoke-TernaryAsPipe -Description "PSCX alias"
Set-Alias :?? Pscx\Invoke-NullCoalescing -Description "PSCX alias"
Set-Alias ?? Pscx\Invoke-NullCoalescingAsPipe -Description "PSCX alias"
<condition_expression> |?: <true_expression> <false_expression>
<variable_expression> |?? <alternate_expression>