Что означает $($variableName) в расширяемых строках в PowerShell?

Я видел несколько примеров сценариев онлайн, которые используют это. Совсем недавно я увидел это в скрипте по автоматизации TFS:

[string] $fields = "Title=$($taskTitle);Description=$($taskTitle);Assigned To=$($assignee);"
$fields += "Area Path=$($areaPath);Iteration Path=$($iterationPath);Discipline=$($taskDisciplineArray[$i]);Priority=$($i+1);"
$fields += "Estimate=$($taskEstimateArray[$i]);Remaining Work=$($taskRemainingArray[$i]);Completed Work=$($tasktaskCompletedArray[$i])"

Из того, что я могу сказать, $($taskTitle) кажется эквивалентным $taskTitle, Я что-то пропустил? Есть ли причина использовать круглые скобки и дополнительный знак доллара?

2 ответа

Решение

Синтаксис помогает в оценке выражения внутри него.

$arr = @(1,2,3)

$msg1 = "$arr.length"
echo $msg1 # prints 1 2 3.length - .length was treated as part of the string

$msg2 = "$($arr.length)"
echo $msg2 # prints 3

Вы можете прочитать больше на http://ss64.com/ps/syntax-operators.html

Чтобы дополнить полезный ответ Амита Джорджа дополнительной справочной информацией:

Из того, что я могу сказать, $($taskTitle) кажется эквивалентным $taskTitle,

Действительно, в контексте "..."расширяемая строка:

  • Вы не должны $(...)спростой ссылкой на переменную, такую ​​как$taskTitle или же $env:HOME

    • Иногда вы должны (или можете выбрать) использовать форму${taskTitle}или же${env:HOME}то есть {...} вокруг идентификатора - чтобы устранить неоднозначность имени переменной от последующих символов в строке.
  • Вам нужно$(...)для всего остального:

    • доступ к собственности; например:
      "count is: $($var.Count)"
    • встраивание выражения; например:
      "path prefix: $($var + '/')"
    • встраивание целых команд (возможно, даже нескольких); например:
      "file names: $(Get-ChildItem *.txt | Select-Object -ExpandProperty Name)"

Короче:

  • $(...) внутри "..."необходим для чего-либо, кроме простых ссылок на переменные, и позволяет вставлять целые операторы внутрь "..."; как обычно, когда строка оценивается, $(...) часть заменяется выходом (stringified) из встроенного оператора (ов).

  • Если вы не хотите думать о том, когда $(...) есть и не нужно, вы можете использовать его всегда (например, $($taskTitle)), но учтите, что набирать текст громоздко и визуально "шумно".

    • Предостережение: есть крайний случай, когда поведение $($var)это не то же самое, что$var / ${var}а именно если $varэтоколлекция(реализующая[System.Collections.IEnumerable]) который содержит толькоодин элемент- см. комментарии PetSerAl ниже.
  • Если значение / встроенного оператора ссылочной переменной уже не является строкой, онопреобразуется в строку с помощью.NET.ToString() метод с заметным завихрением в том, что типы, которые поддерживают строковую классификацию, подвергаются строковой классификациисинвариантной культурой, которая, в общем-то, похожа на американско-английский формат; например,"$(1.2)" всегда дает 1.2даже в культурах, где, является десятичной отметкой; см. этот мой ответ для большего.

Документация:

Официальное название для$(...)являетсяоператором подвыражения, как (кратко) задокументировано вGet-Help about_Operators, хотя объяснение там не обсуждает конкретное использование оператора в контексте расширяемых строк.

Наоборот,Get-Help about_Quoting_Rules, который обсуждает строковые литералы, включая расширяемые строки, показывает только примеры $(...) использовать в контексте расширяемых строк.

Другие вопросы по тегам