답변:
Powershell 7은 Powershell의 기본 null 병합, null 조건부 할당 및 삼항 연산자를 도입합니다.
Null 통합
$null ?? 100 # Result is 100
"Evaluated" ?? (Expensive-Operation "Not Evaluated") # Right side here is not evaluated
Null 조건부 할당
$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
분명히 이것은 모든 사람의 취향에 맞지 않을 것이지만 당신이 찾고있는 것일 수 있습니다.
Thomas가 언급했듯이 C # 버전과 위 버전의 또 다른 미묘한 차이점은 C #이 인수의 단락을 수행하지만 함수 / 별칭을 포함하는 Powershell 버전은 항상 모든 인수를 평가한다는 것입니다. 이것이 문제라면 if
표현 형식을 사용하십시오 .
The variable '$myval' cannot be retrieved because it has not been set.
.
$myval = $null
테스트를 수행하기 전에 설정 하면 오류가 사라집니다.
$null -ne $a
지금은 괜찮은 참조를 찾을 수 없습니다.
PowerShell 7은 많은 새로운 기능을 도입하고 .NET Framework에서 .NET Core로 마이그레이션합니다. 2020 년 중반 현재 .NET Core에 대한 의존성으로 인해 레거시 버전의 PowerShell을 완전히 대체하지는 않았지만 Microsoft는 Core 제품군이 결국 레거시 Framework 제품군을 대체 할 계획이라고 밝혔습니다. 이 문서를 읽을 때 쯤이면 호환되는 PowerShell 버전이 시스템에 미리 설치되어있을 수 있습니다. 그렇지 않은 경우 https://github.com/powershell/powershell을 참조 하십시오 .
당 문서 , 다음 연산자는 밖으로의 상자 PowerShell을 7.0에서 지원됩니다
null 병합에 대해 예상 한대로 작동합니다.
$x = $a ?? $b ?? $c ?? 'default value'
$y ??= 'default value'
삼항 연산자가 도입되었으므로 이제 다음이 가능하지만 null 병합 연산자를 추가하면 불필요합니다.
$x = $a -eq $null ? $b : $a
7.0 부터는 문서 ( 1 , 2 )에 설명 된대로 PSNullConditionalOperators
선택적 기능이 활성화 된 경우 다음도 사용할 수 있습니다 .
?.
?[]
여기에는 몇 가지주의 사항이 있습니다.
${}
변수 이름에 물음표가 허용되므로 변수는 실험 연산자 중 하나가 뒤에 오는 경우 로 묶어야 합니다. 기능이 실험 상태에서 전환되는 경우에 해당되는지 확실하지 않습니다 ( 문제 # 11379 참조 ). 예를 들어 ${x}?.Test()
는 new 연산자를 사용하지만 라는 변수에서 $x?.Test()
실행 Test()
됩니다 $x?
.?(
TypeScript에서 오는 경우 예상 할 수있는 연산자 가 없습니다 . 다음은 작동하지 않습니다.$x.Test?()
7 이전의 PowerShell 버전에는 실제 Null 병합 연산자 또는 최소한 이러한 동작을 수행 할 수있는 연산자가 있습니다. 그 연산자는 -ne
다음과 같습니다.
# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]
# Output:
alpha
null이 아닌 모든 항목의 배열을 만들기 때문에 null 병합 연산자보다 좀 더 다재다능합니다.
$items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false
$instances = $items -ne $null
[string]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() }))
# Result:
System.String, System.Int32, System.Int32, System.String, System.Object[],
System.Boolean, System.Boolean
-eq
유사하게 작동하므로 null 항목을 계산하는 데 유용합니다.
($null, 'a', $null -eq $null).Length
# Result:
2
그러나 어쨌든 다음은 C #의 ??
연산자 를 미러링하는 일반적인 경우입니다 .
'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output
이 설명은 익명 사용자의 편집 제안을 기반으로합니다. 감사합니다, 누구든!
작업 순서에 따라 다음 순서로 작동합니다.
,
연산자 값의 배열이 테스트 될 만든다.-ne
이 경우, 널 - 지정된 값과 일치하는 배열에서 어떤 아이템 아웃 조작 필터. 결과는 1 단계에서 만든 배열과 동일한 순서로 null이 아닌 값의 배열입니다.[0]
필터링 된 배열의 첫 번째 요소를 선택하는 데 사용됩니다.단순화 :
C #의 Null 병합 연산자와 달리 첫 번째 단계는 배열을 만드는 것이므로 가능한 모든식이 평가됩니다.
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
및 -join
(및 단항 대시? 즉 -4
또는 -'56'
)입니다.
이것은 질문의 전반부에 대한 대답의 절반에 불과하므로 원하는 경우 1/4 대답이지만 사용하려는 기본값이 실제로 유형의 기본값 인 경우 null 병합 연산자에 대한 훨씬 더 간단한 대안이 있습니다. :
string s = myval ?? "";
Powershell에서 다음과 같이 작성할 수 있습니다.
([string]myval)
또는
int d = myval ?? 0;
Powershell로 번역 :
([int]myval)
존재하지 않을 수도 있고 존재한다면 원치 않는 공백이있을 수있는 xml 요소를 처리 할 때이 중 첫 번째가 유용하다는 것을 알았습니다.
$name = ([string]$row.td[0]).Trim()
문자열로의 캐스트는 요소가 null 인 것을 방지하고 Trim()
실패 위험을 방지합니다 .
([string]$null)
-> ""
유사한 것 같다 "유용하지만, 불행한 부작용":(
$null, $null, 3 | Select -First 1
보고
3
Powershell Community Extensions 모듈 을 설치하면 다음을 사용할 수 있습니다.
?? Invoke-NullCoalescing의 별칭입니다.
$s = ?? {$myval} {"New Value"}
? : Invoke-Ternary의 별칭입니다.
$x = ?: {$myval -eq $null} {""} {$otherval}
마지막으로 PowerShell 7에는 Null Coalescing 할당 연산자가 있습니다 !
PS > $null ?? "a"
a
PS > "x" ?? "y"
x
PS > $x = $null
PS > $x ??= "abc"
PS > $x
abc
PS > $x ??= "xyz"
PS > $x
abc
병합을 사용할 때 빈 문자열을 null로 처리해야하는 경우가 종종 있습니다. 저는 이것에 대한 함수를 작성했습니다.이 함수 는 단순한 null 병합을위한 통합을 위해 Zenexer 의 솔루션을 사용한 다음 null 또는 빈 검사를 위해 Keith Hill 을 사용 하고 내 함수가 둘 다 수행 할 수 있도록 플래그로 추가했습니다.
이 함수의 장점 중 하나는 예외를 발생시키지 않고 모든 요소가 null (또는 비어 있음) 인 경우도 처리한다는 것입니다. PowerShell이 배열 입력을 처리하는 방식 덕분에 임의의 많은 입력 변수에 사용할 수도 있습니다.
function Coalesce([string[]] $StringsToLookThrough, [switch]$EmptyStringAsNull) {
if ($EmptyStringAsNull.IsPresent) {
return ($StringsToLookThrough | Where-Object { $_ } | Select-Object -first 1)
} else {
return (($StringsToLookThrough -ne $null) | Select-Object -first 1)
}
}
이렇게하면 다음 테스트 결과가 생성됩니다.
Null coallesce tests:
1 (w/o flag) - empty/null/'end' :
1 (with flag) - empty/null/'end' : end
2 (w/o flag) - empty/null :
2 (with flag) - empty/null :
3 (w/o flag) - empty/null/$false/'end' :
3 (with flag) - empty/null/$false/'end' : False
4 (w/o flag) - empty/null/"$false"/'end' :
4 (with flag) - empty/null/"$false"/'end' : False
5 (w/o flag) - empty/'false'/null/"$false"/'end':
5 (with flag) - empty/'false'/null/"$false"/'end': false
테스트 코드 :
Write-Host "Null coalesce tests:"
Write-Host "1 (w/o flag) - empty/null/'end' :" (Coalesce '', $null, 'end')
Write-Host "1 (with flag) - empty/null/'end' :" (Coalesce '', $null, 'end' -EmptyStringAsNull)
Write-Host "2 (w/o flag) - empty/null :" (Coalesce('', $null))
Write-Host "2 (with flag) - empty/null :" (Coalesce('', $null) -EmptyStringAsNull)
Write-Host "3 (w/o flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end')
Write-Host "3 (with flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end' -EmptyStringAsNull)
Write-Host "4 (w/o flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end')
Write-Host "4 (with flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end' -EmptyStringAsNull)
Write-Host "5 (w/o flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end')
Write-Host "5 (with flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end' -EmptyStringAsNull)
내가 얻을 수있는 가장 가까운 것은 : $Val = $MyVal |?? "Default Value"
위 의 null 병합 연산자 를 다음과 같이 구현했습니다 .
function NullCoalesc {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$Default
)
if ($Value) { $Value } else { $Default }
}
Set-Alias -Name "??" -Value NullCoalesc
조건 삼항 연산자는 similary 방식으로 구현 될 수있다.
function ConditionalTernary {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$First,
[Parameter(Position=1)]$Second
)
if ($Value) { $First } else { $Second }
}
Set-Alias -Name "?:" -Value ConditionalTernary
그리고 다음과 같이 사용됩니다. $Val = $MyVal |?: $MyVal "Default Value"