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