Подтвердить что ты не робот

Что означает $ ($ 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. Я что-то пропустил? Есть ли причина использовать круглые скобки и дополнительный знак доллара?

4b9b3361

Ответ 1

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

$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.

Ответ 2

В дополнение к полезному ответу Амит Джордж с дополнительной справочной информацией:

Из того, что я могу сказать, $($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() метода, с заметным твистом, что типы, которые поддерживают культуру чувствительных stringification являются строковым с инвариантной культурой, которая, грубо говоря, похож на американско-английский формат; например, "$(1.2)" всегда дает 1.2, даже в тех культурах, где , десятичный знак; см. этот мой ответ для большего.

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

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

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