“ $(($ i ++))”背后的魔力是什么?

时间:2019-06-16 10:13:56

标签: powershell

下面是一小段代码,它们以1秒的间隔输出1 2 3 ...

while ($true) {
  sleep -s 1
  "$(($i++))"
}

怎么可能?

2 个答案:

答案 0 :(得分:10)

评论中有很好的指针,但让我深入一点:

$i++ 的解释:

  • $i++使用++increment operator)将变量$i的值增加1 ,如C#和C / C ++等语言所熟悉的。正如预期的那样,减量运算符--也存在)。

    • 由于++定位在变量后 后缀形式),所以在变量值后 已在语句中使用;将其放在变量之前-++$i(前缀 形式)将先执行 递增;如果单独使用递增/递减运算,则该区别是不相关的。

    • 假定
    • $i包含数字类型的实例,否则会发生错误;如果尚未初始化变量$i,则其值实际上是$null,PowerShell会将其强制转换为[int]类型的0。因此,$i++在其声明的上下文中求值为0,然后再递增为1

  • $i++这样的增减表达式被视为赋值 -您可以将其视为$i = $i + 1-并且PowerShell中的赋值不产生任何输出(它们不返回任何内容;它们仅更新变量的值)。

围绕(...)的{​​{1}}的解释

  • 通过将赋值括在括号($i++中,您将其转换为表达式,这表示赋值的通过 传递,以便它可以参与更大的表达式;例如。:
    • (...) ...没有输出-仅将值$i = 0分配给变量0
    • $i ...输出($i = 1):由于1,也会输出分配的值。
    • (...) ...预递增:将(++$i)的值递增到$i并输出该值。
    • 2 ...递减:输出($i++),当前值 then 将值递增到2

围绕3的{​​{1}}的解释

  • $(...)subexpression operator )是将一个或多个语句的输出嵌入到不直接支持语句的上下文中所必需的。值得注意的是,您可以使用它将命令输出嵌入可扩展字符串($i++))中,即执行字符串内插

    • 请注意,$(...)仅用于嵌入表达式(例如,"..."中包含的内容,属性访问($(...)),索引,({{ 1}})和方法调用((...))和命令(例如$foo.bar),而不是仅用于变量引用,例如$foo[0]。有关PowerShell中可扩展字符串的更多信息,请参见this answer
  • 在您的简单示例中,虽然没有严格要求可扩展的字符串-仅$foo.Baz()会产生看起来相同的输出 [1] -{{1} }可用于使Get-Date的值成为较大字符串的一部分;例如,"Honey, I'm $HOME"打印($i++)$(...),...


[1] ($i++) number ,而"Iteration #$(($i++))" string ,其中,数字发生在字符串插值中。 尽管通常 会产生相同的控制台输出,但是对于非整数数字(例如"Iteration #0"),它实际上可能有所不同,因为直接输出适用 culture < / em>敏感的字符串化,而字符串插值是区域性-不变。因此,在有效的区域性使用"Iteration #1"作为小数点的情况下-例如($i++)"$(($i++)"打印-适当地区域性-作为1.2打印到控制台,而{ {1}} 始终打印为,

答案 1 :(得分:0)

在powershell中,赋值也是表达式。但是通常不会显示表达式的输出。因为函数内部的任何输出都将由它返回。

PS C:\users\js> $a = ($b = 1)
PS C:\users\js> $a
1
PS C:\users\js> $b
1    

顺便说一句,$()不仅仅用于内部字符串。您可以在其中用分号分隔多个语句,并使用诸如foreach和if之类的关键字,然后将其放置在可以放置表达式(管道)的任何位置。

PS C:\users\js> $(if ($true) { echo hi }; echo there) | measure


Count    : 2
Average  :
Sum      :
Maximum  :
Minimum  :
Property :