Wszystko, czego potrzebujesz, aby dowiedzieć się więcej o $nullEverything you wanted to know about $null

Program PowerShell $null często wydaje się być prosty, ale ma wiele wszystkie szczegóły.The PowerShell $null often appears to be simple but it has a lot of nuances. Spójrzmy na $null siebie, aby wiedzieć, co się dzieje w przypadku nieoczekiwanego uruchomienia w $null wartości.Let's take a close look at $null so you know what happens when you unexpectedly run into a $null value.

Uwaga

[Oryginalna wersja][] tego artykułu pojawiła się w blogu zapisanym przez program @KevinMarquette .The original version of this article appeared on the blog written by @KevinMarquette. Zespół programu PowerShell Dziękujemy za udostępnienie tej zawartości.The PowerShell team thanks Kevin for sharing this content with us. Zapoznaj się z blogiem w witrynie PowerShellExplained.com.Please check out his blog at PowerShellExplained.com.

Co to jest wartość NULL?What is NULL?

Wartość NULL można traktować jako nieznaną lub pustą.You can think of NULL as an unknown or empty value. Zmienna ma wartość NULL, dopóki nie zostanie przypisana do niej wartość lub obiekt.A variable is NULL until you assign a value or an object to it. Może to być istotne, ponieważ istnieją polecenia, które wymagają wartości i generują błędy, jeśli wartość jest RÓWNa NULL.This can be important because there are some commands that require a value and generate errors if the value is NULL.

$null programu PowerShellPowerShell $null

$null jest automatyczną zmienną w programie PowerShell służącą do reprezentowania wartości NULL.$null is an automatic variable in PowerShell used to represent NULL. Można przypisać ją do zmiennych, użyć jej w porównaniach i użyć jej jako symbolu zastępczego dla wartości NULL w kolekcji.You can assign it to variables, use it in comparisons and use it as a place holder for NULL in a collection.

Program PowerShell traktuje $null jako obiekt o wartości null.PowerShell treats $null as an object with a value of NULL. Jest to inne niż to, czego można oczekiwać, jeśli pochodzą z innego języka.This is different than what you may expect if you come from another language.

Przykłady $nullExamples of $null

Za każdym razem, gdy spróbujesz użyć zmiennej, która nie została zainicjowana, wartość to $null .Anytime you try to use a variable that you have not initialized, the value is $null. Jest to jeden z najczęstszych sposobów, które $null zobaczyć wartości w kodzie.This is one of the most common ways that $null values sneak into your code.

PS> $null -eq $undefinedVariable
True

Jeśli wystąpi konieczność wpisania nazwy zmiennej, program PowerShell widzi ją jako inną zmienną, a wartość to $null .If you happen to mistype a variable name then PowerShell sees it as a different variable and the value is $null.

Innymi sposobami znajdowania $null wartości są te, które pochodzą z innych poleceń, które nie dają żadnych wyników.The other way you find $null values is when they come from other commands that don't give you any results.

PS> function Get-Nothing {}
PS> $value = Get-Nothing
PS> $null -eq $value
True

Wpływ $nullImpact of $null

$null wartości wpływają na kod w różny sposób w zależności od tego, gdzie są wyświetlane.$null values impact your code differently depending on where they show up.

W ciągachIn strings

Jeśli używasz $null ciągu, jest to wartość pusta (lub pusty ciąg).If you use $null in a string, then it's a blank value (or empty string).

PS> $value = $null
PS> Write-Output "The value is $value"
The value is

Jest to jedna z przyczyn, w których należy umieścić nawiasy wokół zmiennych podczas ich używania w komunikatach dziennika.This is one of the reasons that I like to place brackets around variables when using them in log messages. Jest to jeszcze ważniejsze, aby identyfikować krawędzie wartości zmiennych, gdy wartość jest na końcu ciągu.It's even more important to identify the edges of your variable values when the value is at the end of the string.

PS> $value = $null
PS> Write-Output "The value is [$value]"
The value is []

Dzięki temu puste ciągi i $null wartości są łatwe w obsłudze.This makes empty strings and $null values easy to spot.

W równaniu numerycznymIn numeric equation

Gdy $null wartość jest używana w równaniu liczbowym, wyniki są nieprawidłowe, jeśli nie wydają błędu.When a $null value is used in a numeric equation then your results are invalid if they don't give an error. Czasami $null wynikiem są 0 wyniki i inne czasy, w których wykonuje cały wynik $null .Sometimes the $null evaluates to 0 and other times it makes the whole result $null. Oto przykład z mnożeniem, które daje 0 lub $null w zależności od kolejności wartości.Here is an example with multiplication that gives 0 or $null depending on the order of the values.

PS> $null * 5
PS> $null -eq ( $null * 5 )
True

PS> 5 * $null
0
PS> $null -eq ( 5 * $null )
False

Zamiast kolekcjiIn place of a collection

Kolekcja umożliwia korzystanie z indeksu w celu uzyskania dostępu do wartości.A collection allow you use an index to access values. Jeśli spróbujesz wykonać indeksowanie do kolekcji, która faktycznie null , zostanie wyświetlony następujący błąd: Cannot index into a null array .If you try to index into a collection that is actually null, you get this error: Cannot index into a null array.

PS> $value = $null
PS> $value[10]
Cannot index into a null array.
At line:1 char:1
+ $value[10]
+ ~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

Jeśli masz kolekcję, ale próbujesz uzyskać dostęp do elementu, który nie znajduje się w kolekcji, uzyskasz $null wynik.If you have a collection but try to access an element that is not in the collection, you get a $null result.

$array = @( 'one','two','three' )
$null -eq $array[100]
True

Zamiast obiektuIn place of an object

Jeśli spróbujesz uzyskać dostęp do właściwości lub właściwości podrzędnej obiektu, który nie ma określonej właściwości, uzyskasz $null wartość taką jak dla niezdefiniowanej zmiennej.If you try to access a property or sub property of an object that doesn't have the specified property, you get a $null value like you would for an undefined variable. Nie ma znaczenia, czy zmienna jest $null lub rzeczywisty obiekt w tym przypadku.It doesn't matter if the variable is $null or an actual object in this case.

PS> $null -eq $undefined.some.fake.property
True

PS> $date = Get-Date
PS> $null -eq $date.some.fake.property
True

Metoda w wyrażeniu o wartości nullMethod on a null-valued expression

Wywołanie metody w $null obiekcie zgłasza RuntimeException .Calling a method on a $null object throws a RuntimeException.

PS> $value = $null
PS> $value.toString()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $value.tostring()
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Zawsze, gdy widzę frazę You cannot call a method on a null-valued expression , pierwsze, czego szukam, są umieszczane w miejscu, w którym wywołujemy metodę dla zmiennej bez uprzedniego sprawdzenia $null .Whenever I see the phrase You cannot call a method on a null-valued expression then the first thing I look for are places where I am calling a method on a variable without first checking it for $null.

Sprawdzanie $nullChecking for $null

Być może zauważono, że zawsze umieszczam po $null lewej stronie podczas sprawdzania $null w obszarze Moje przykłady.You may have noticed that I always place the $null on the left when checking for $null in my examples. Jest to zamierzone i akceptowane jako najlepsze rozwiązanie programu PowerShell.This is intentional and accepted as a PowerShell best practice. Istnieją sytuacje, w których umieszczenie ich po prawej stronie nie daje oczekiwanego wyniku.There are some scenarios where placing it on the right doesn't give you the expected result.

Zapoznaj się z tym następnym przykładem i spróbuj przewidzieć wyniki:Look at this next example and try to predict the results:

if ( $value -eq $null )
{
    'The array is $null'
}
if ( $value -ne $null )
{
    'The array is not $null'
}

Jeśli nie definiuję $value , pierwszy z nich szacuje się $true i naszym komunikatem jest The array is $null .If I do not define $value, the first one evaluates to $true and our message is The array is $null. Pułapka jest taka, że można ją utworzyć $value , która pozwala na $falseThe trap here is that it's possible to create a $value that allows both of them to be $false

$value = @( $null )

W tym przypadku $value jest tablicą zawierającą $null .In this case, the $value is an array that contains a $null. -eqSprawdza wszystkie wartości w tablicy i zwraca $null , że jest dopasowany.The -eq checks every value in the array and returns the $null that is matched. Ta wartość jest równa $false .This evaluates to $false. -neZwraca wszystkie elementy, które nie są zgodne $null , i w tym przypadku nie ma wyników (jest to również wynikiem $false ).The -ne returns everything that doesn't match $null and in this case there are no results (This also evaluates to $false). Żaden $true z nich nie jest jeszcze taki, jakby wyglądał jak jeden z nich.Neither one is $true even though it looks like one of them should be.

Nie tylko można utworzyć wartość, która powoduje, że oba z nich są oceniane na $false , można utworzyć wartość, w której obie te wartości są szacowane $true .Not only can we create a value that makes both of them evaluate to $false, it's possible to create a value where they both evaluate to $true. Mathias Jessen ( @IISResetMe ) ma [dobry wpis][] , który omówieniach w tym scenariuszu.Mathias Jessen (@IISResetMe) has a good post that dives into that scenario.

PSScriptAnalyzer i programu vscodePSScriptAnalyzer and VSCode

Moduł PSScriptAnalyzer ma regułę, która sprawdza, czy ten problem został wywołany PSPossibleIncorrectComparisonWithNull .The PSScriptAnalyzer module has a rule that checks for this issue called PSPossibleIncorrectComparisonWithNull.

PS> Invoke-ScriptAnalyzer ./myscript.ps1

RuleName                              Message
--------                              -------
PSPossibleIncorrectComparisonWithNull $null should be on the left side of equality comparisons.

Ponieważ VS Code używa również reguł PSScriptAnalyser, podświetla lub identyfikuje ten problem w skrypcie.Because VS Code uses the PSScriptAnalyser rules too, it also highlights or identifies this as a problem in your script.

Prosta klauzula IF CheckSimple if check

Typowym sposobem, w jaki ludzie sprawdzają, czy nie $null wartość, jest użycie prostej if() instrukcji bez porównania.A common way that people check for a non-$null value is to use a simple if() statement without the comparison.

if ( $value )
{
    Do-Something
}

Wartość jest równa $null $false .If the value is $null, this evaluates to $false. Jest to łatwe do odczytania, ale należy pamiętać, że szuka dokładnie tego, czego oczekujesz.This is easy to read, but be careful that it's looking for exactly what you're expecting it to look for. Odczytaję ten wiersz kodu jako:I read that line of code as:

Jeśli $value ma wartość.If $value has a value.

Ale nie jest to cały wątek.But that's not the whole story. Ten wiersz jest rzeczywiście mówiący:That line is actually saying:

Jeśli $value nie jest $null lub 0 lub $false lub empty stringIf $value is not $null or 0 or $false or an empty string

Oto bardziej kompletny przykład tej instrukcji.Here is a more complete sample of that statement.

if ( $null -ne $value -and
        $value -ne 0 -and
        $value -ne '' -and
        $value -ne $false )
{
    Do-Something
}

Idealnie sprawdza się w przypadku, gdy if zapamiętasz, że inne wartości liczą się tak, jak $false i nie tylko wtedy, gdy zmienna ma wartość.It's perfectly OK to use a basic if check as long as you remember those other values count as $false and not just that a variable has a value.

Wystąpił problem podczas refaktoryzacji kodu kilka dni temu.I ran into this issue when refactoring some code a few days ago. Miało to podstawowe właściwości.It had a basic property check like this.

if ( $object.property )
{
    $object.property = $value
}

Chcę przypisać wartość do właściwości Object tylko wtedy, gdy istnieje.I wanted to assign a value to the object property only if it existed. W większości przypadków oryginalny obiekt miał wartość, która będzie Szacowana $true w if instrukcji.In most cases, the original object had a value that would evaluate to $true in the if statement. Ale wystąpił problem polegający na tym, że wartość była czasami niedostępna.But I ran into an issue where the value was occasionally not getting set. Kod został debugowany i stwierdzono, że obiekt miał właściwość, ale miał pustą wartość ciągu.I debugged the code and found that the object had the property but it was a blank string value. Uniemożliwiło to uzyskanie aktualizacji z poprzednią logiką.This prevented it from ever getting updated with the previous logic. Dlatego dodano poprawne $null sprawdzenie i wszystko działało.So I added a proper $null check and everything worked.

if ( $null -ne $object.property )
{
    $object.property = $value
}

Są to niewielkie usterki, takie jak te, które są trudne do zaewidencjonowania i umożliwiają agresywne sprawdzanie wartości dla $null .It's little bugs like these that are hard to spot and make me aggressively check values for $null.

$null. Liczbą$null.Count

Jeśli spróbujesz uzyskać dostęp do właściwości na $null wartości, właściwość jest również $null .If you try to access a property on a $null value, that the property is also $null. countWłaściwość jest wyjątkiem od tej reguły.The count property is the exception to this rule.

PS> $value = $null
PS> $value.count
0

Gdy masz $null wartość, count jest to 0 .When you have a $null value, then the count is 0. Specjalna właściwość jest dodawana przez program PowerShell.This special property is added by PowerShell.

Parametr PSCustomObject Liczbą[PSCustomObject] Count

Prawie wszystkie obiekty w programie PowerShell mają tę Właściwość Count.Almost all objects in PowerShell have that count property. Jednym z ważnych wyjątków jest program [PSCustomObject] Windows PowerShell 5,1 (ten problem został rozwiązany w programie PowerShell 6,0).One important exception is the [PSCustomObject] in Windows PowerShell 5.1 (This is fixed in PowerShell 6.0). Nie ma właściwości count, dlatego można uzyskać $null wartość przy próbie jej użycia.It doesn't have a count property so you get a $null value if you try to use it. Wywołaję to tutaj, aby nie próbować użyć .Count zamiast $null sprawdzenia.I call this out here so that you don't try to use .Count instead of a $null check.

Uruchomienie tego przykładu w programie Windows PowerShell 5,1 i programu PowerShell 6,0 daje różne wyniki.Running this example on Windows PowerShell 5.1 and PowerShell 6.0 gives you different results.

$value = [PSCustomObject]@{Name='MyObject'}
if ( $value.count -eq 1 )
{
    "We have a value"
}

Pusta wartość nullEmpty null

Istnieje jeden typ specjalny $null , który działa inaczej niż inne.There is one special type of $null that acts differently than the others. Chcę, aby wywoływać ten element pusty, $null ale jest to naprawdę element System. Management. Automation. Internal. AutomationNull.I am going to call it the empty $null but it's really a System.Management.Automation.Internal.AutomationNull. Ta wartość $null jest pusta, którą uzyskuje się jako wynik funkcji lub bloku skryptu, który zwraca Nothing (wynik void).This empty $null is the one you get as the result of a function or script block that returns nothing (a void result).

PS> function Get-Nothing {}
PS> $nothing = Get-Nothing
PS> $null -eq $nothing
True

Jeśli porównasz ją z usługą $null , uzyskasz $null wartość.If you compare it with $null, you get a $null value. Gdy jest używana w ocenie, w której wartość jest wymagana, wartość jest zawsze $null .When used in an evaluation where a value is required, the value is always $null. Ale jeśli umieścisz go wewnątrz tablicy, jest on traktowany jak pustą tablicę.But if you place it inside an array, it's treated the same as an empty array.

PS> $containempty = @( @() )
PS> $containnothing = @($nothing)
PS> $containnull = @($null)

PS> $containempty.count
0
PS> $containnothing.count
0
PS> $containnull.count
1

Możesz mieć tablicę, która zawiera jedną $null wartość, a jej count jest 1 .You can have an array that contains one $null value and its count is 1. Ale jeśli umieścisz pusty wynik wewnątrz tablicy, nie będzie on liczony jako element.But if you place an empty result inside an array then it's not counted as an item. Licznik ma wartość 0 .The count is 0.

Jeśli jest traktowana jako $null Kolekcja pusta, to jest pusta.If you treat the empty $null like a collection, then it's empty.

PotokPipeline

Różnica polega na tym, że podczas korzystania z potoku zostanie wyświetlona pozostała część.The primary place you see the difference is when using the pipeline. Można potoku $null wartości, ale nie wartości pustej $null .You can pipe a $null value but not an empty $null value.

PS> $null | ForEach-Object{ Write-Output 'NULL Value' }
'NULL Value'
PS> $nothing | ForEach-Object{ Write-Output 'No Value' }

W zależności od kodu należy uwzględnić $null w logice.Depending on your code, you should account for the $null in your logic.

Sprawdzaj $null najpierwEither check for $null first

  • Odfiltruj wartość null w potoku ( ... | Where {$null -ne $_} | ... )Filter out null on the pipeline (... | Where {$null -ne $_} | ...)
  • Obsługuj ją w funkcji potokuHandle it in the pipeline function

foreachforeach

Jedną z ulubionych funkcji programu foreach jest to, że nie jest ona wyliczana na $null kolekcji.One of my favorite features of foreach is that it doesn't enumerate over a $null collection.

foreach ( $node in $null )
{
    #skipped
}

Dzięki temu nie trzeba $null sprawdzać kolekcji przed jej wyliczeniem.This saves me from having to $null check the collection before I enumerate it. Jeśli masz kolekcję $null wartości, $node nadal może być $null .If you have a collection of $null values, the $node can still be $null.

Instrukcja foreach zaczęła działać w ten sposób z programem PowerShell 3,0.The foreach started working this way with PowerShell 3.0. Jeśli chcesz mieć starszą wersję, to nie jest to przypadek.If you happen to be on an older version, then this is not the case. Jest to jedna z ważnych zmian, które należy wiedzieć, gdy numer powrotny jest zgodny z 2,0.This is one of the important changes to be aware of when back-porting code for 2.0 compatibility.

Typy wartościValue types

Technicznie można tylko typy referencyjne $null .Technically, only reference types can be $null. Ale program PowerShell jest bardzo Generous i umożliwia określenie zmiennych jako dowolnego typu.But PowerShell is very generous and allows for variables to be any type. Jeśli zdecydujesz się na silnie wpisać typ wartości, nie może to być $null .If you decide to strongly type a value type, it cannot be $null. Program PowerShell konwertuje $null do wartości domyślnej dla wielu typów.PowerShell converts $null to a default value for many types.

PS> [int]$number = $null
PS> $number
0

PS> [bool]$boolean = $null
PS> $boolean
False

PS> [string]$string = $null
PS> $string -eq ''
True

Istnieją typy, które nie mają prawidłowej konwersji z $null .There are some types that do not have a valid conversion from $null. Te typy generują Cannot convert null to type błąd.These types generate a Cannot convert null to type error.

PS> [datetime]$date = $null
Cannot convert null to type "System.DateTime".
At line:1 char:1
+ [datetime]$date = $null
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

Parametry funkcjiFunction parameters

Użycie jednoznacznie wpisanych wartości w parametrach funkcji jest bardzo popularne.Using a strongly typed values in function parameters is very common. Ogólnie uczymy się definiować typy naszych parametrów, nawet jeśli nie zdefiniowano typów innych zmiennych w naszych skryptach.We generally learn to define the types of our parameters even if we tend not to define the types of other variables in our scripts. Możesz już mieć pewne zmienne o jednoznacznie określonym typie w funkcjach, a nawet nie należy ich zapamiętać.You may already have some strongly typed variables in your functions and not even realize it.

function Do-Something
{
    param(
        [String] $Value
    )
}

Gdy tylko ustawisz typ parametru jako string , wartość nie może być nigdy $null .As soon as you set the type of the parameter as a string, the value can never be $null. Często sprawdza się, czy wartość jest wyświetlana, jeśli $null użytkownik podał wartość.It's common to check if a value is $null to see if the user provided a value or not.

if ( $null -ne $Value ){...}

$Value jest pustym ciągiem, '' gdy nie podano wartości.$Value is an empty string '' when no value is provided. Zamiast tego użyj zmiennej automatycznej $PSBoundParameters.Value .Use the automatic variable $PSBoundParameters.Value instead.

if ( $null -ne $PSBoundParameters.Value ){...}

$PSBoundParameters zawiera tylko parametry, które zostały określone podczas wywołania funkcji.$PSBoundParameters only contains the parameters that were specified when the function was called. Możesz również użyć ContainsKey metody do sprawdzenia właściwości.You can also use the ContainsKey method to check for the property.

if ( $PSBoundParameters.ContainsKey('Value') ){...}

IsNotNullOrEmptyIsNotNullOrEmpty

Jeśli wartość jest ciągiem, można użyć funkcji statycznego ciągu, aby sprawdzić, czy wartość jest $null lub pusty ciąg w tym samym czasie.If the value is a string, you can use a static string function to check if the value is $null or an empty string at the same time.

if ( -not [string]::IsNullOrEmpty( $value ) ){...}

Często używam tej funkcji, gdy wiemy, że typ wartości powinien być ciągiem.I find myself using this often when I know the value type should be a string.

Gdy sprawdzim $nullWhen I $null check

Jestem skryptem obronnym.I am a defensive scripter. Za każdym razem, gdy wywołujemy funkcję i przypiszesz ją do zmiennej, zaznaczam ją $null .Anytime I call a function and assign it to a variable, I check it for $null.

$userList = Get-ADUser kevmar
if ($null -ne $userList){...}

Mam wiele woli przy użyciu if lub foreach za pomocą try/catch .I much prefer using if or foreach over using try/catch. Nie chcę otrzymywać problemów, nadal używam try/catch wielu.Don't get me wrong, I still use try/catch a lot. Ale jeśli mogę sprawdzić pod kątem błędu lub pustego zestawu wyników, mogę zezwolić na obsługę wyjątków dla prawdziwych wyjątków.But if I can test for an error condition or an empty set of results, I can allow my exception handling be for true exceptions.

Mogę również sprawdzić $null przed indeksem do wartości lub wywołać metody dla obiektu.I also tend to check for $null before I index into a value or call methods on an object. Te dwie akcje kończą się niepowodzeniem dla $null obiektu, dlatego ważne jest, aby je najpierw sprawdzić.These two actions fail for a $null object so I find it important to validate them first. Te scenariusze zostały już omówione wcześniej w tym wpisie.I already covered those scenarios earlier in this post.

Scenariusz braku wynikówNo results scenario

Ważne jest, aby wiedzieć, że różne funkcje i polecenia obsługują scenariusz braku wyników inaczej.It's important to know that different functions and commands handle the no results scenario differently. Wiele poleceń programu PowerShell zwraca wartość pustą $null i błąd w strumieniu błędu.Many PowerShell commands return the empty $null and an error in the error stream. Ale inne zwracają wyjątki lub udostępniają obiekt stanu.But others throw exceptions or give you a status object. Nadal możesz wiedzieć, jak używane polecenia są obsługiwane w przypadku braku wyników i scenariuszy błędów.It's still up to you to know how the commands you use deal with the no results and error scenarios.

Inicjowanie do $nullInitializing to $null

Jeden wykonywać, który został pobrany, inicjuje wszystkie moje zmienne przed ich użyciem.One habit that I have picked up is initializing all my variables before I use them. Musisz to zrobić w innych językach.You are required to do this in other languages. W górnej części funkcji lub jako Pętla foreach Zdefiniuję wszystkie używane wartości.At the top of my function or as I enter a foreach loop, I define all the values that I'm using.

Oto scenariusz, który chcę zrobić blisko.Here is a scenario that I want you to take a close look at. Jest to przykład błędu, który musiał wcześniej się połączyć.It's an example of a bug I had to chase down before.

function Do-Something
{
    foreach ( $node in 1..6 )
    {
        try
        {
            $result = Get-Something -ID $node
        }
        catch
        {
            Write-Verbose "[$result] not valid"
        }

        if ( $null -ne $result )
        {
            Update-Something $result
        }
    }
}

Oczekiwane jest to, że Get-Something zwraca wynik lub pustą wartość $null .The expectation here is that Get-Something returns either a result or an empty $null. Jeśli wystąpi błąd, rejestrujemy go.If there is an error, we log it. Następnie sprawdzimy, czy mamy prawidłowy wynik przed jego przetworzeniem.Then we check to make sure we got a valid result before processing it.

Usterka jest ukrywana w tym kodzie Get-Something , gdy zgłasza wyjątek i nie przypisuje wartości do $result .The bug hiding in this code is when Get-Something throws an exception and doesn't assign a value to $result. Nie jest to możliwe przed przypisaniem, więc nie są one jeszcze przypisane $null do $result zmiennej.It fails before the assignment so we don't even assign $null to the $result variable. $result nadal zawiera poprzednie prawidłowe $result z innych iteracji.$result still contains the previous valid $result from other iterations. Update-Something do wykonania wiele razy w tym samym obiekcie w tym przykładzie.Update-Something to execute multiple times on the same object in this example.

Ustawiam $result $null bezpośrednio wewnątrz pętli Foreach przed użyciem go w celu ograniczenia tego problemu.I set $result to $null right inside the foreach loop before I use it to mitigate this issue.

foreach ( $node in 1..6 )
{
    $result = $null
    try
    {
        ...

Problemy dotyczące zakresuScope issues

Pozwala to również ograniczyć problemy dotyczące określania zakresu.This also helps mitigate scoping issues. W tym przykładzie przypiszemy wartości $result over i over w pętli.In that example, we assign values to $result over and over in a loop. Ale ponieważ program PowerShell zezwala na wartości zmiennych spoza funkcji, aby przerównać się do zakresu bieżącej funkcji, inicjowanie ich wewnątrz funkcji ogranicza błędy, które można wprowadzić w ten sposób.But because PowerShell allows variable values from outside the function to bleed into the scope of the current function, initializing them inside your function mitigates bugs that can be introduced that way.

Niezainicjowana zmienna w funkcji nie jest $null ustawiona na wartość w zakresie nadrzędnym.An uninitialized variable in your function is not $null if it's set to a value in a parent scope. Zakres nadrzędny może być inną funkcją, która wywołuje funkcję i używa tych samych nazw zmiennych.The parent scope could be another function that calls your function and uses the same variable names.

Jeśli zajmiemy ten sam Do-something przykład i usuniesz pętlę, chcę, aby coś wyglądało jak w tym przykładzie:If I take that same Do-something example and remove the loop, I would end up with something that looks like this example:

function Invoke-Something
{
    $result = 'ParentScope'
    Do-Something
}

function Do-Something
{
    try
    {
        $result = Get-Something -ID $node
    }
    catch
    {
        Write-Verbose "[$result] not valid"
    }

    if ( $null -ne $result )
    {
        Update-Something $result
    }
}

Jeśli wywołanie Get-Something wygeneruje wyjątek, wówczas $null Wyszukiwanie znajduje się w $result Invoke-Something .If the call to Get-Something throws an exception, then my $null check finds the $result from Invoke-Something. Zainicjowanie wartości wewnątrz funkcji ogranicza ten problem.Initializing the value inside your function mitigates this issue.

Zmienne nazewnictwa są trudne i często autor może używać tych samych nazw zmiennych w wielu funkcjach.Naming variables is hard and it's common for an author to use the same variable names in multiple functions. Wiemy, że używam $node , przez $result $data cały czas.I know I use $node,$result,$data all the time. Jest to bardzo proste w przypadku wartości z różnych zakresów do wyświetlenia w miejscach, w których nie powinny być.So it would be very easy for values from different scopes to show up in places where they should not be.

Przekieruj dane wyjściowe do $nullRedirect output to $null

Mam mówić o $null wartościach dla tego całego artykułu, ale temat nie został ukończony, jeśli nie wspominałem o przekierowaniu danych wyjściowych do programu $null .I have been talking about $null values for this entire article but the topic is not complete if I didn't mention redirecting output to $null. Istnieją przypadki, gdy masz polecenia, które zawierają informacje wyjściowe lub obiekty, które chcesz pominąć.There are times when you have commands that output information or objects that you want to suppress. Przekierowywanie danych wyjściowych do $null tego programu.Redirecting output to $null does that.

Out — wartość nullOut-Null

Polecenie out-null to wbudowana Metoda przekierowania danych potoku do programu $null .The Out-Null command is the built-in way to redirect pipeline data to $null.

New-Item -Type Directory -Path $path | Out-Null

Przypisz do $nullAssign to $null

Można przypisać wyniki polecenia do tego $null samego efektu jak w przypadku użycia Out-Null .You can assign the results of a command to $null for the same effect as using Out-Null.

$null = New-Item -Type Directory -Path $path

Ponieważ $null jest wartością stałą, nigdy nie można jej zastąpić.Because $null is a constant value, you can never overwrite it. Nie lubię tego, jak wygląda w kodzie, ale często wykonuje się to szybciej niż Out-Null .I don't like the way it looks in my code but it often performs faster than Out-Null.

Przekieruj do $nullRedirect to $null

Do wysyłania danych wyjściowych można również użyć operatora przekierowania $null .You can also use the redirection operator to send output to $null.

New-Item -Type Directory -Path $path > $null

Jeśli pracujesz z plikami wykonywalnymi wiersza polecenia, które są wyprowadzane przez różne strumienie.If you're dealing with command-line executables that output on the different streams. Można przekierować wszystkie strumienie wyjściowe w $null następujący sposób:You can redirect all output streams to $null like this:

git status *> $null

PodsumowanieSummary

Poznamy wiele rzeczy na ten temat i wiemy, że ten artykuł jest bardziej pofragmentowany niż większość głębokiego omówieniach.I covered a lot of ground on this one and I know this article is more fragmented than most of my deep dives. Oznacza to, że wartości można wypróbować $null w wielu różnych miejscach w programie PowerShell, a wszystkie wszystkie szczegóły są specyficzne dla miejsca, w którym je znajdziesz.That is because $null values can pop up in many different places in PowerShell and all the nuances are specific to where you find it. Mam nadzieję, że przejdziemy do tego, aby lepiej zrozumieć $null i poznać bardziej zasłonięte scenariusze, które mogą być w nim uruchomione.I hope you walk away from this with a better understanding of $null and an awareness of the more obscure scenarios you may run into.