为什么需要一对额外的支架?

时间:2012-01-23 21:37:18

标签: powershell

以下powershell脚本

"one","two","three" | % { "$(($l++)): $_" }

将打印

1: one
2: two
3: three

但是,删除$l++

周围的括号后
"one","two","three" | % { "$($l++): $_" }

它会打印

: one
: two
: three

4 个答案:

答案 0 :(得分:12)

这是因为$l++无效声明。在powershell某些类型的 表达式在用作语句时不会显示。 无效语句包括赋值和递增/递减运算符。当它们在表达式中使用时,它们返回一个值,但是当它们用作独立语句时,它们不返回任何值。 Bruce Payette Windows Powershell in Action 中对此进行了详细解释:

  

增量和减量运算符几乎不包含在PowerShell中   因为他们引入了一个问题。在C和C#等语言中,使用时   其中一个运营商作为声明:   $ A ++   没有显示。这是因为C和C#中的语句不返回值。在   但是,PowerShell所有语句都返回一个值。这导致了混乱。人   会编写这样的脚本:

$sum=0
$i=0
while ($i -lt 10) { $sum += $i; $i++ }
$sum
  

并惊讶地看到数字1到10显示。这是因为$ a ++   返回一个值,PowerShell显示每个语句的结果。这个   是如此令人困惑,我们几乎从语言中删除了这些运算符。然后我们   找到了一个无效陈述的想法。基本上,这意味着某些类型的   表达式在用作语句时不会显示。无效的陈述包括   赋值和递增/递减运算符。当它们被用于   表达式,它们返回一个值,但是当它们被用作独立语句时,它们就是   没有回报。同样,这是其中一个不会影响您使用PowerShell的细节,而不是让它按预期工作。 (来源:Windows Powershell in Action)

答案 1 :(得分:4)

我认为这是PowerShell团队做出的一项设计决策,旨在避免因PowerShell输出返回值而产生的意外。许多C / C#人都希望以下函数只输出1而不是@(0,1)。

function foo {
  $i = 0
  $i++
  $i
}

因此语句形式$i++在递增之前不会输出$ i的值。如果您想要这种行为,PowerShell允许您通过将增量(或减量)语句直接放在表达式中来获得该行为,例如:

function foo {
  $i = 0
  ($i++)
  $i
}

这将输出@(0,1)。

Bruce Payette在Windows PowerShell in Action 2nd Edition的第5章中对此进行了讨论。递增和递减运算符是“无效语句”。从书中引用:

  

基本上,这意味着某些类型的表达式在用作时   语句,不显示。无效陈述包括分配   语句和递增/递减运算符。当增量和   递减在表达式中使用,它们返回一个值,但是何时返回   它们被用作独立的声明,它们没有返回值。

答案 2 :(得分:1)

这是因为$l++没有返回任何内容,:

$l = 0
$l++   #nothing
$l #gives 1
$l++   #nothing
($l++)  #gives 2

这样做是为了在您返回管道时不会产生混淆。有效地,

$l++$l = $l+ 1,因此不返回任何内容。

您希望看到的是$l = $l + 1; $l,这就是您必须($l++)的原因。

答案 3 :(得分:0)

我认为它需要完成两项任务:

  1. 在内括号
  2. 上执行$l++(增加变量)
  3. 检索外括号中发生的$l值。
  4. 以下是对此的说明:

    $l = 0
    "$($l++ ; $l)"
    

    输出:1其中

    $l = 0
    "$($l++)"
    

    不输出任何内容。

    为了接收输出,我需要在子表达式中使用两个语句。否则,唯一发生的事情是$l递增,但不检索其值。