Вот небольшой фрагмент кода, который выводит 1 2 3 ... с интервалом в 1 секунду.
while ($true) {
sleep -s 1
"$(($i++))"
}
Как это возможно?
++Увеличивает значение переменной, назначаемого свойства или элемента массива на 1.@Lee_Dailey, спасибо, теперь это имеет гораздо больше смысла
@ Мэтт, нет, это не нужно. Вам нужно сначала обработать то, что находится внутри скобок. В противном случае будет интерпретироваться только $i, а ++ будет частью строки.





В комментариях есть хорошие указатели, но позвольте мне копнуть немного глубже:
Объяснение $i++:
$i++ использует ++, оператор приращения, для увеличения значения переменной $i на 1, знакомый по таким языкам, как C# и C/C++. Как и ожидалось, также существует дополнительный оператор уменьшение, --).
Поскольку ++ расположен после переменной (форма постфикс), увеличение происходит после, значение переменной было использовано в операторе; поместив его в до, переменная - ++$i (форма приставка) будет выполнять увеличение первый; если операция увеличения/уменьшения используется изолированно, это различие не имеет значения.
$i предполагается, что он содержит экземпляр типа числовой, иначе возникает ошибка; если переменная $i не была инициализирована, ее значение фактически равно $null, которое PowerShell приводит к [int]-типу 0. Таким образом, $i++ оценивается как 0 в контексте своего утверждения и впоследствии увеличивается до 1.
выражение увеличения/уменьшения, такое как $i++, обрабатывается как назначение — вы можете думать об этом как $i = $i + 1 — и присваивания в PowerShell не производить вывод (они ничего не возвращают, они только обновляют значение переменной).
Объяснение (...) вокруг $i++:
(...)) вы превращаете в выражение, что означает передается стоимость назначения через, чтобы он мог участвовать в более крупном выражении; например.:
$i = 0 ... без вывода - просто присваивает значение 0 переменной $i.($i = 1) ... выводит 1: благодаря (...) также выводится присвоенное значение.(++$i) ... предварительное увеличение: увеличивает значение $i до 2 и выводит это значение.($i++) ... пост-декремент: выводит 2, текущее значение, тогда увеличивает значение до 3.Объяснение $(...) вокруг ($i++):
$(...), оператор подвыражения необходим для встраивания вывода одного или даже нескольких операторов в контекстах, где операторы напрямую не поддерживаются. Примечательно, что вы можете используйте его для встраивания вывода команды в расширяемая строка ("..."), т. е. для выполнения интерполяция строк.
$(...) требуется только для встраивания выражения (например, что-то, заключенное в (...), доступ к свойствам ($foo.bar), индексация, ($foo[0]) и вызовы методов ($foo.Baz())) и команды (например, Get-Date), а не просто ссылки на переменные, такие как в "Honey, I'm $HOME". Дополнительные сведения о расширяемых строках в PowerShell см. в статье этот ответ.Хотя в вашем простом примере нет строгой необходимости в расширяемой строке — просто ($i++) будет производить вывод, который выглядит так же [1] — $(...) полезен для того, чтобы сделать значение ($i++) частью большей строки; например, "Iteration #$(($i++))" для печати "Iteration #0", "Iteration #1", ...
[1] ($i++) is a number, whereas "$(($i++)" is a string, where the to-string conversion of the number happened as part of the string interpolation.
While that typically results in the same console output, it can actually differ for non-integral numbers such as 1.2, because direct output applies culture-sensitive stringification, whereas string interpolation is culture-invariant. Thus, with a culture in effect that uses , as the decimal mark -e.g, fr-FR, 1.2 prints - culture-appropriately - as 1,2 to the console, whereas "$(1.2)"always prints as 1.2
В 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 :
Выражения назначения не (выражения в смысле наличия стоимость), но могут быть и выражениями превратился в - посредством заключив их в скобки.
@ mklement0 Присваивание обычно не выводит свое значение. Но я могу найти примеры, где оно действует как выражение без лишних скобок. $a = $b = 1;if ($a = 1) { 'yes' }
Да, и отсутствие вывода его значения делает его нет выражением. Ваш пример представляет собой один оператор присваивания (хотя он включает несколько переменных), а не выражение. Хотя в вашем примере линия размыта, полезнее думать о присваивании как о не-выражении, которое вы должны превратить в выражение с помощью (...), если хотите, чтобы оно выводило присвоенное значение.
powershell может сделать
variable squeezingтак, чтобы переменная назначалась/обновлялась И отображалась за один шаг. похоже, это то, что происходит в коде, который вы разместили. внешний"$()"не нужен, хотя. вы можете заменить эту строку на($i++)и получить тот же результат.