У меня есть следующий упрощенный код:
# My "original" Null-coalescing operator
function or { $args[0] ? $args[0] : $args[1] }
function c1 { "code $($args ? $args : './')" }
function c2 { "code $($args ?? './')" }
function c3 { "code $(or $args './')" }
Вывод выглядит следующим образом:
❯ c1
code './'
❯ c2
code
❯ c3
code './'
❯ c1 .gitconfig
code .gitconfig
❯ c2 .gitconfig
code .gitconfig
❯ c3 .gitconfig
code .gitconfig
Я просто не понимаю, почему оператор ?? не работает так, как я ожидал в выводе c2Case 1. К сожалению, это разрушает мои потенциальные варианты использования оператора.
Может кто-нибудь объяснить, почему это так?





Это не удается, потому что $args никогда не является null, даже вне функции. Когда нет Несвязанных аргументов или вне контекста функции или блока сценария, это всегда пустой массив объектов ([array]::Empty[object]() или [object[]]::new(0)):
PS ..\pwsh> $args.GetType()
Namespace: System
Access Modifiers Name
------ --------- ----
public sealed class object[] : Array, ICloneable...
PS ..\pwsh> $null -eq $args
False
Однако вы можете индексировать 0, чтобы все работало правильно:
function c2 { "code $($args[0] ?? './')" }
Или принудительно выполнить его перечисление:
function c2 { "code $($($args) ?? './')" }
В обоих случаях выводится:
c2 # => code ./
c2 foo # => code foo
@DmitrijDrandarov да, я полностью с тобой согласен. Но в данном случае (по моему мнению) ?? ($null -eq $args) поступает правильно, потому что пустой массив — нет null. Это логическое приведение, которое не имеет смысла, поскольку pwsh пустой массив ([bool] $args) находится в логическом контексте false (бессмыслица).
Еще один интересный эффект дизайна, который я заметил, заключается в том, что $false ?? ... также работает так же, поскольку $false -ne $null. Хотя это имеет смысл, поскольку это «нулевое объединение», но, очевидно, сбивает с толку несоответствие с ?. Думаю, я задокументирую это, если кто-то наткнется на этот пост.
Я чувствую, что
??работает иначе, чем?, — это сомнительный дизайнерский выбор команды Powershell, но принудительное перечисление, как вы предложили, — отличный обходной путь. Спасибо 🙂