Есть ли в PowerShell нулевой оператор объединения?
Я хотел бы иметь возможность выполнять эти команды C # в PowerShell:
var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
Есть ли в PowerShell нулевой оператор объединения?
Я хотел бы иметь возможность выполнять эти команды C # в PowerShell:
var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
Powershell 7 представляет встроенное объединение null, условное присвоение null и тернарные операторы в Powershell.
Нулевое слияние
$null ?? 100 # Result is 100
"Evaluated" ?? (Expensive-Operation "Not Evaluated") # Right side here is not evaluated
Нулевое условное присвоение
$x = $null
$x ??= 100 # $x is now 100
$x ??= 200 # $x remains 100
Тернарный оператор
$true ? "this value returned" : "this expression not evaluated"
$false ? "this expression not evaluated" : "this value returned"
Расширения Powershell Community Extensions не требуются, вы можете использовать стандартные операторы Powershell if в качестве выражения:
variable = if (condition) { expr1 } else { expr2 }
Итак, что касается замены вашего первого выражения C #:
var s = myval ?? "new value";
становится одним из следующих (в зависимости от предпочтений):
$s = if ($myval -eq $null) { "new value" } else { $myval }
$s = if ($myval -ne $null) { $myval } else { "new value" }
или в зависимости от того, что может содержать $ myval, вы можете использовать:
$s = if ($myval) { $myval } else { "new value" }
и второе выражение C # отображается аналогичным образом:
var x = myval == null ? "" : otherval;
становится
$x = if ($myval -eq $null) { "" } else { $otherval }
Честно говоря, они не очень быстрые и далеко не так удобны в использовании, как формы C #.
Вы также можете обернуть его очень простой функцией, чтобы сделать ее более читаемой:
function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } }
$s = Coalesce $myval "new value"
или, возможно, как IfNull:
function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } }
$s = IfNull $myval "new value" $myval
$x = IfNull $myval "" $otherval
Как видите, очень простая функция может дать вам некоторую свободу синтаксиса.
ОБНОВЛЕНИЕ: еще один вариант, который следует учитывать в сочетании, - это более общая функция IsTrue:
function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } }
$x = IfTrue ($myval -eq $null) "" $otherval
Затем объедините это с возможностью Powershell объявлять псевдонимы, которые немного похожи на операторы, в результате вы получите:
New-Alias "??" Coalesce
$s = ?? $myval "new value"
New-Alias "?:" IfTrue
$ans = ?: ($q -eq "meaning of life") 42 $otherval
Ясно, что это не всем придется по вкусу, но может быть именно то, что вы ищете.
Как отмечает Томас, еще одно тонкое различие между версией C # и приведенной выше заключается в том, что C # выполняет сокращение аргументов, но версии Powershell, включающие функции / псевдонимы, всегда будут оценивать все аргументы. Если это проблема, используйте if
форму выражения.
The variable '$myval' cannot be retrieved because it has not been set.
.$myval = $null
до проведения теста, ошибка должна исчезнуть.$null -ne $a
не могу найти достойную ссылку сейчас, но это давняя практика.PowerShell 7 и новее
PowerShell 7 представляет множество новых функций и выполняет миграцию с .NET Framework на .NET Core. По состоянию на середину 2020 года он не полностью заменил устаревшие версии PowerShell из-за зависимости от .NET Core, но Microsoft указала, что они намерены, чтобы семейство Core в конечном итоге заменило устаревшее семейство Framework. К тому времени, как вы это прочитаете, в вашей системе может быть предустановлена совместимая версия PowerShell; если нет, см. https://github.com/powershell/powershell .
Согласно документации , в PowerShell 7.0 «из коробки» поддерживаются следующие операторы:
??
??=
... ? ... : ...
Они работают так, как и следовало ожидать от нулевого объединения:
Поскольку был введен тернарный оператор, теперь возможно следующее, хотя в этом нет необходимости, учитывая добавление нулевого оператора объединения:
Начиная с версии 7.0, если включена
PSNullConditionalOperators
дополнительная функция, также доступны следующие функции , как описано в документации ( 1 , 2 ):?.
?[]
У них есть несколько предостережений:
${}
if, за которым следует один из экспериментальных операторов, поскольку в именах переменных разрешены вопросительные знаки. Неясно, будет ли это так, если / когда функции выйдут из экспериментального статуса (см. Проблему № 11379 ). Например,${x}?.Test()
использует оператор new, но$x?.Test()
работаетTest()
с переменной с именем$x?
.?(
Оператора нет, как и следовало ожидать, если вы работаете с TypeScript. Следующее не сработает:$x.Test?()
PowerShell 6 и ранее
Версии PowerShell до 7 действительно имеют фактический нулевой оператор объединения или, по крайней мере, оператор, способный к такому поведению. Этот оператор
-ne
:Он немного более универсален, чем оператор объединения с нулевым значением, поскольку он создает массив всех ненулевых элементов:
-eq
работает аналогично, что полезно для подсчета нулевых записей:Но в любом случае вот типичный случай зеркального отражения
??
оператора C # :объяснение
Это объяснение основано на предложении редактирования от анонимного пользователя. Спасибо, кто бы вы ни были!
В зависимости от порядка операций это работает в следующем порядке:
,
Оператор создает массив значений для тестирования.-ne
операторском отфильтровывает любые элементы из массива , которые соответствуют указанному значению - в данном случае, нулевой. Результатом является массив ненулевых значений в том же порядке, что и массив, созданный на шаге 1.[0]
используется для выбора первого элемента фильтруемого массива.Упрощая это:
Предостережения
В отличие от оператора объединения NULL в C #, каждое возможное выражение будет оцениваться, поскольку первым шагом является создание массива.
источник
function DidItRun($a) { Write-Host "It ran with $a"; return $a }
и бегите,((DidItRun $null), (DidItRun 'alpha'), 1 -ne $null)[0]
чтобы увидеть это.,
такой высокий приоритет. Для всех, кто не понимает, как это работает,($null, 'alpha', 1 -ne $null)[0]
то же самое, что и(($null, 'alpha', 1) -ne $null)[0]
. Фактически, единственные два оператора «тире» с более высоким приоритетом - это-split
and-join
(и унарное тире? Т.е.-4
или-'56'
).Это только половина ответа на первую половину вопроса, поэтому четвертый ответ, если хотите, но есть гораздо более простая альтернатива оператору объединения null при условии, что значение по умолчанию, которое вы хотите использовать, на самом деле является значением по умолчанию для типа :
Может быть записано в Powershell как:
Или
переводится на Powershell:
Я обнаружил, что первый из них полезен при обработке элемента xml, который может не существовать и который, если бы он существовал, мог иметь нежелательные пробелы вокруг него:
Приведение к строке защищает от нулевого значения элемента и предотвращает любой риск
Trim()
сбоя.источник
([string]$null)
->""
похоже на "полезный, но досадный побочный эффект" :($null, $null, 3 | Select -First 1
возвращается
3
источник
Если вы установите модуль расширений сообщества Powershell, вы можете использовать:
?? это псевдоним для Invoke-NullCoalescing.
?: это псевдоним Invoke-Ternary.
источник
Наконец, PowerShell 7 получил операторы присваивания Null Coalescing !
источник
источник
источник
Часто я обнаруживаю, что мне также нужно рассматривать пустую строку как нулевую при использовании coalesce. В итоге я написал функцию для этого, которая использует решение Zenexer для объединения для простого объединения NULL, а затем использовал Keith Hill для нулевой или пустой проверки и добавил это в качестве флага, чтобы моя функция могла выполнять и то, и другое.
Одним из преимуществ этой функции является то, что она также обрабатывает все элементы, равные нулю (или пустым), без создания исключения. Его также можно использовать для произвольного количества входных переменных, благодаря тому, как PowerShell обрабатывает входные данные массива.
Это дает следующие результаты теста:
Код теста:
источник
Ближайшее, что я могу найти, это:
$Val = $MyVal |?? "Default Value"
Я реализовал нулевой оператор объединения для вышеуказанного следующим образом:
Условная тройная оператор может быть реализована в Similary образом.
И используется как:
$Val = $MyVal |?: $MyVal "Default Value"
источник