ค้นหาเว็บไซต์

ทุกสิ่งที่คุณอยากรู้เกี่ยวกับ $null


PowerShell $null มักจะดูเรียบง่ายแต่มีความแตกต่างมากมาย มาดูรายละเอียดที่ $null กันดีกว่า เพื่อให้คุณทราบว่าจะเกิดอะไรขึ้นเมื่อคุณพบค่า $null โดยไม่คาดคิด

บันทึก

ต้นฉบับของบทความนี้ปรากฏบนบล็อกที่เขียนโดย @KevinMarquette ทีม PowerShell ขอขอบคุณ Kevin สำหรับการแบ่งปันเนื้อหานี้กับเรา โปรดตรวจสอบบล็อกของเขาที่ PowerShellExplained.com

ค่าว่างคืออะไร?

คุณสามารถคิดว่า NULL เป็นค่าที่ไม่รู้จักหรือว่างเปล่า ตัวแปรจะเป็น NULL จนกว่าคุณจะกำหนดค่าหรือวัตถุให้กับตัวแปรนั้น สิ่งนี้อาจมีความสำคัญเนื่องจากมีคำสั่งบางคำสั่งที่จำเป็นต้องมีค่าและสร้างข้อผิดพลาดหากค่าเป็น NULL

PowerShell $null

$null เป็นตัวแปรอัตโนมัติใน PowerShell ที่ใช้แทนค่า NULL คุณสามารถกำหนดให้กับตัวแปร ใช้ในการเปรียบเทียบ และใช้เป็นที่ยึดสำหรับ NULL ในคอลเลกชันได้

PowerShell ถือว่า $null เป็นวัตถุที่มีค่าเป็น NULL สิ่งนี้แตกต่างจากที่คุณคาดหวังหากคุณมาจากภาษาอื่น

ตัวอย่างของ $null

เมื่อใดก็ตามที่คุณพยายามใช้ตัวแปรที่คุณยังไม่ได้เตรียมใช้งาน ค่าจะเป็น $null นี่เป็นวิธีหนึ่งที่พบบ่อยที่สุดที่ค่า $null แอบเข้าไปในโค้ดของคุณ

PS> $null -eq $undefinedVariable
True

หากคุณบังเอิญพิมพ์ชื่อตัวแปรผิด PowerShell จะเห็นว่ามันเป็นตัวแปรอื่นและค่าจะเป็น $null

อีกวิธีหนึ่งที่คุณค้นหาค่า $null คือเมื่อค่าเหล่านั้นมาจากคำสั่งอื่นที่ไม่ให้ผลลัพธ์ใดๆ แก่คุณ

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

ผลกระทบของ $null

ค่า $null ส่งผลต่อโค้ดของคุณแตกต่างกันไป ขึ้นอยู่กับตำแหน่งที่แสดง

ในสตริง

หากคุณใช้ $null ในสตริง จะเป็นค่าว่าง (หรือสตริงว่าง)

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

นี่คือหนึ่งในเหตุผลที่ฉันชอบใส่วงเล็บรอบตัวแปรเมื่อใช้ตัวแปรเหล่านั้นในข้อความบันทึก การระบุขอบของค่าตัวแปรนั้นสำคัญยิ่งกว่าเมื่อค่าอยู่ท้ายสตริง

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

ทำให้มองเห็นสตริงว่างและค่า $null ได้ง่าย

ในสมการเชิงตัวเลข

เมื่อใช้ค่า $null ในสมการตัวเลข ผลลัพธ์ของคุณจะไม่ถูกต้องหากไม่มีข้อผิดพลาด บางครั้ง $null ประเมินเป็น 0 และบางครั้งก็ทำให้ผลลัพธ์ทั้งหมด $null นี่คือตัวอย่างที่มีการคูณที่ให้ 0 หรือ $null ขึ้นอยู่กับลำดับของค่า

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

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

แทนการสะสม

คอลเลกชันอนุญาตให้คุณใช้ดัชนีเพื่อเข้าถึงค่า หากคุณพยายามที่จะจัดทำดัชนีในคอลเลกชันที่เป็น null จริง ๆ คุณจะได้รับข้อผิดพลาดนี้: ไม่สามารถจัดทำดัชนีเป็นอาร์เรย์ว่าง

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

หากคุณมีคอลเลกชันแต่พยายามเข้าถึงองค์ประกอบที่ไม่ได้อยู่ในคอลเลกชัน คุณจะได้รับผลลัพธ์ $null

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

แทนที่วัตถุ

หากคุณพยายามเข้าถึงคุณสมบัติหรือคุณสมบัติย่อยของออบเจ็กต์ที่ไม่มีคุณสมบัติที่ระบุ คุณจะได้รับค่า $null เช่นเดียวกับที่คุณทำกับตัวแปรที่ไม่ได้กำหนด ไม่สำคัญว่าตัวแปรจะเป็น $null หรือวัตถุจริงในกรณีนี้

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

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

วิธีการในการแสดงออกที่มีค่า Null

การเรียกเมธอดบนอ็อบเจ็กต์ $null จะทำให้เกิด 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

เมื่อใดก็ตามที่ฉันเห็นวลี คุณไม่สามารถเรียกใช้เมธอดในนิพจน์ที่เป็นค่าว่างได้ สิ่งแรกที่ฉันค้นหาคือตำแหน่งที่ฉันกำลังเรียกใช้เมธอดบนตัวแปรโดยไม่ตรวจสอบ $ก่อน โมฆะ.

กำลังตรวจสอบ $null

คุณอาจสังเกตเห็นว่าฉันมักจะวาง $null ทางด้านซ้ายเสมอเมื่อตรวจสอบ $null ในตัวอย่างของฉัน นี่เป็นความตั้งใจและยอมรับว่าเป็นแนวทางปฏิบัติที่ดีที่สุดของ PowerShell มีบางสถานการณ์ที่การวางไว้ทางด้านขวาไม่ได้ให้ผลลัพธ์ตามที่คาดหวัง

ดูตัวอย่างต่อไปนี้แล้วลองทำนายผลลัพธ์:

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

หากฉันไม่ได้กำหนด $value อันแรกจะประเมินเป็น $true และข้อความของเราคือ The array is $null กับดักที่นี่คือคุณสามารถสร้าง $value ที่อนุญาตให้ทั้งคู่เป็น $false

$value = @( $null )

ในกรณีนี้ $value คืออาร์เรย์ที่มี $null -eq ตรวจสอบทุกค่าในอาร์เรย์และส่งกลับ $null ที่ตรงกัน ซึ่งจะประเมินเป็น $false -ne ส่งคืนทุกอย่างที่ไม่ตรงกับ $null และในกรณีนี้จะไม่มีผลลัพธ์ (ซึ่งจะประเมินเป็น $false ด้วย) ไม่มีอันใดอันหนึ่ง $true แม้ว่าดูเหมือนว่าอันใดอันหนึ่งควรจะเป็นก็ตาม

ไม่เพียงแต่เราสามารถสร้างค่าที่ทำให้ทั้งคู่ประเมินเป็น $false เท่านั้น แต่ยังสามารถสร้างค่าที่ทั้งคู่ประเมินเป็น $true ได้ด้วย Mathias Jessen (@IISResetMe) มีโพสต์ที่ดีซึ่งเจาะลึกสถานการณ์นั้น

PSScriptAnalyzer และ VSCode

โมดูล PSScriptAnalyzer มีกฎที่ตรวจสอบปัญหานี้ที่เรียกว่า PSPossibleIncorrectComparisonWithNull

PS> Invoke-ScriptAnalyzer ./myscript.ps1

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

เนื่องจาก VS Code ใช้กฎ PSScriptAnalyser เช่นกัน จึงเน้นหรือระบุว่านี่เป็นปัญหาในสคริปต์ของคุณ

ง่าย ๆ หากตรวจสอบ

วิธีทั่วไปที่ผู้ใช้ตรวจสอบค่าที่ไม่ใช่ $null คือการใช้คำสั่ง if() ธรรมดาโดยไม่มีการเปรียบเทียบ

if ( $value )
{
    Do-Something
}

หากค่าเป็น $null ค่านี้จะประเมินเป็น $false เนื้อหานี้อ่านง่าย แต่ควรระวังว่ามันกำลังมองหาสิ่งที่คุณต้องการอย่างแน่นอน ฉันอ่านโค้ดบรรทัดนั้นว่า:

ถ้า $value มีค่า

แต่นั่นไม่ใช่เรื่องราวทั้งหมด จริงๆ แล้วบรรทัดนั้นบอกว่า:

หาก $value ไม่ใช่ $null หรือ 0 หรือ $false หรือเป็นสตริงว่างหรืออาร์เรย์ว่าง

นี่คือตัวอย่างที่สมบูรณ์ยิ่งขึ้นของข้อความนั้น

if ( $null -ne $value -and
        $value -ne 0 -and
        $value -ne '' -and
        ($value -isnot [array] -or $value.Length -ne 0) -and
        $value -ne $false )
{
    Do-Something
}

เป็นเรื่องปกติที่จะใช้การตรวจสอบ if พื้นฐาน ตราบใดที่คุณจำได้ว่าค่าอื่นๆ เหล่านั้นนับเป็น $false และไม่ใช่แค่ว่าตัวแปรมีค่าเท่านั้น

ฉันพบปัญหานี้เมื่อปรับโครงสร้างโค้ดใหม่เมื่อไม่กี่วันที่ผ่านมา มันมีการตรวจสอบคุณสมบัติพื้นฐานเช่นนี้

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

ฉันต้องการกำหนดค่าให้กับคุณสมบัติของวัตถุเฉพาะเมื่อมีอยู่เท่านั้น ในกรณีส่วนใหญ่ ออบเจ็กต์ต้นฉบับมีค่าที่จะประเมินเป็น $true ในคำสั่ง if แต่ฉันพบปัญหาที่ไม่สามารถตั้งค่าเป็นบางครั้ง ฉันแก้ไขโค้ดแล้วและพบว่าวัตถุมีคุณสมบัติ แต่เป็นค่าสตริงว่าง สิ่งนี้ทำให้ไม่สามารถอัปเดตด้วยตรรกะก่อนหน้าได้ ดังนั้นฉันจึงเพิ่มการตรวจสอบ $null ที่เหมาะสมและทุกอย่างทำงานได้

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

จุดบกพร่องเล็กๆ น้อยๆ เช่นนี้ตรวจพบได้ยาก และทำให้ฉันตรวจสอบค่า $null อย่างจริงจัง

$null.นับ

หากคุณพยายามเข้าถึงคุณสมบัติด้วยค่า $null คุณสมบัตินั้นก็จะเป็น $null เช่นกัน คุณสมบัติ count เป็นข้อยกเว้นของกฎนี้

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

เมื่อคุณมีค่า $null ดังนั้น count จะเป็น 0 คุณสมบัติพิเศษนี้ถูกเพิ่มโดย PowerShell

[PSCustomObject] นับ

วัตถุเกือบทั้งหมดใน PowerShell มีคุณสมบัติการนับนั้น ข้อยกเว้นที่สำคัญประการหนึ่งคือ [PSCustomObject] ใน Windows PowerShell 5.1 (ซึ่งได้รับการแก้ไขแล้วใน PowerShell 6.0) มันไม่มีคุณสมบัติการนับดังนั้นคุณจะได้รับค่า $null หากคุณพยายามใช้ ฉันเรียกสิ่งนี้ที่นี่เพื่อที่คุณจะได้ไม่ต้องพยายามใช้ .Count แทนการตรวจสอบ $null

การเรียกใช้ตัวอย่างนี้บน Windows PowerShell 5.1 และ PowerShell 6.0 จะให้ผลลัพธ์ที่แตกต่างออกไป

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

ค่าว่างนับได้

มี $null ประเภทพิเศษประเภทหนึ่งที่ทำงานแตกต่างจากประเภทอื่น ฉันจะเรียกมันว่า null นับได้ แต่จริงๆ แล้วมันคือ System.Management.Automation.Internal.AutomationNull ค่าว่างที่นับได้นี้เป็นค่าที่คุณได้รับจากผลลัพธ์ของฟังก์ชันหรือบล็อกสคริปต์ที่ไม่ส่งคืนสิ่งใดเลย (ผลลัพธ์เป็นโมฆะ)

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

หากคุณเปรียบเทียบกับ $null คุณจะได้รับค่า $null เมื่อใช้ในการประเมินค่าที่ต้องการ ค่าจะเป็น $null เสมอ แต่ถ้าคุณวางไว้ในอาร์เรย์ ก็จะถือว่าเหมือนกับอาร์เรย์ว่าง

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

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

คุณสามารถมีอาร์เรย์ที่มีค่า $null หนึ่งค่าและ count คือ 1 แต่ถ้าคุณวางอาร์เรย์ว่างไว้ภายในอาร์เรย์ จะไม่นับเป็นรายการ จำนวนคือ 0

หากคุณถือว่าค่าว่างที่นับได้เหมือนกับคอลเลกชั่น แสดงว่าคอลเลกชั่นนั้นจะว่างเปล่า

หากคุณส่งค่า Null ที่สามารถนับได้ไปยังพารามิเตอร์ฟังก์ชันที่ไม่ได้พิมพ์อย่างแน่นหนา PowerShell จะบังคับค่า Null ที่สามารถนับได้ให้เป็นค่า $null ตามค่าเริ่มต้น ซึ่งหมายความว่าภายในฟังก์ชัน ค่าจะถือเป็น $null แทนที่จะเป็นประเภท System.Management.Automation.Internal.AutomationNull

ไปป์ไลน์

จุดหลักที่คุณเห็นความแตกต่างคือเมื่อใช้ไปป์ไลน์ คุณสามารถไพพ์ค่า $null ได้ แต่ไม่สามารถนับค่า Null ได้

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

คุณควรคำนึงถึง $null ในตรรกะของคุณ ทั้งนี้ขึ้นอยู่กับรหัสของคุณ

ตรวจสอบ $null ก่อน

  • กรองค่าว่างในไปป์ไลน์ออก (... | โดยที่ {$null -ne $_} | ...)
  • จัดการมันในฟังก์ชั่นไปป์ไลน์

foreach

หนึ่งในคุณสมบัติที่ฉันชื่นชอบของ foreach ก็คือ มันไม่ได้ระบุรวมอยู่ในคอลเลกชัน $null

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

สิ่งนี้ช่วยให้ฉันไม่ต้อง $null ตรวจสอบคอลเลกชันก่อนที่จะแจกแจง หากคุณมีคอลเลกชันของค่า $null $node ยังคงเป็น $null

foreach เริ่มทำงานในลักษณะนี้กับ PowerShell 3.0 หากคุณเป็นเวอร์ชันเก่าก็ไม่เป็นเช่นนั้น นี่เป็นหนึ่งในการเปลี่ยนแปลงที่สำคัญที่ต้องระวังเมื่อโค้ด back-porting สำหรับความเข้ากันได้ 2.0

ประเภทค่า

ในทางเทคนิค เฉพาะประเภทการอ้างอิงเท่านั้นที่สามารถเป็น $null ได้ แต่ PowerShell นั้นใจกว้างมากและอนุญาตให้ตัวแปรเป็นประเภทใดก็ได้ หากคุณตัดสินใจที่จะพิมพ์ประเภทค่าอย่างยิ่ง จะต้องไม่เป็น $null PowerShell แปลง $null เป็นค่าเริ่มต้นสำหรับหลายประเภท

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

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

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

มีบางประเภทที่ไม่มีการแปลงที่ถูกต้องจาก $null ประเภทเหล่านี้สร้างข้อผิดพลาด ไม่สามารถแปลง null เป็นประเภท

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

พารามิเตอร์ฟังก์ชัน

การใช้ค่าที่พิมพ์อย่างยิ่งในพารามิเตอร์ฟังก์ชันเป็นเรื่องปกติมาก โดยทั่วไปเราเรียนรู้ที่จะกำหนดประเภทของพารามิเตอร์ของเรา แม้ว่าเราจะไม่ได้กำหนดประเภทของตัวแปรอื่นๆ ในสคริปต์ของเราก็ตาม คุณอาจมีตัวแปรที่พิมพ์อย่างเข้มงวดอยู่แล้วในฟังก์ชันของคุณแต่ไม่รู้ตัวด้วยซ้ำ

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

ทันทีที่คุณตั้งค่าประเภทของพารามิเตอร์เป็น string ค่าจะต้องไม่เป็น $null เป็นเรื่องปกติที่จะตรวจสอบว่าค่าเป็น $null เพื่อดูว่าผู้ใช้ระบุค่าหรือไม่

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

$Value เป็นสตริงว่าง '' เมื่อไม่ได้ระบุค่า ใช้ตัวแปรอัตโนมัติ $PSBoundParameters.Value แทน

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

$PSBoundParameters มีเฉพาะพารามิเตอร์ที่ระบุเมื่อมีการเรียกใช้ฟังก์ชันเท่านั้น คุณยังสามารถใช้วิธี ContainsKey เพื่อตรวจสอบคุณสมบัติได้

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

IsNotNullOrEmpty

หากค่าเป็นสตริง คุณสามารถใช้ฟังก์ชันสตริงคงที่เพื่อตรวจสอบว่าค่าเป็น $null หรือเป็นสตริงว่างในเวลาเดียวกัน

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

ฉันพบว่าตัวเองใช้สิ่งนี้บ่อยครั้งเมื่อฉันรู้ว่าประเภทค่าควรเป็นสตริง

เมื่อฉันตรวจสอบ $null

ฉันเป็นคนเขียนบทป้องกัน ทุกครั้งที่ฉันเรียกใช้ฟังก์ชันและกำหนดให้กับตัวแปร ฉันจะตรวจสอบ $null

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

ฉันชอบใช้ if หรือ foreach มากกว่าการใช้ try/catch อย่าเข้าใจฉันผิด ฉันยังคงใช้ try/catch บ่อยมาก แต่ถ้าฉันสามารถทดสอบเงื่อนไขข้อผิดพลาดหรือชุดผลลัพธ์ที่ว่างเปล่า ฉันสามารถอนุญาตให้การจัดการข้อยกเว้นของฉันเป็นข้อยกเว้นที่แท้จริงได้

ฉันมักจะตรวจสอบ $null ก่อนที่ฉันจะจัดทำดัชนีเป็นค่าหรือวิธีการเรียกบนวัตถุ การดำเนินการทั้งสองนี้ล้มเหลวสำหรับวัตถุ $null ดังนั้นฉันจึงพบว่าการตรวจสอบความถูกต้องก่อนเป็นสิ่งสำคัญ ฉันได้กล่าวถึงสถานการณ์เหล่านั้นแล้วก่อนหน้านี้ในโพสต์นี้

ไม่มีสถานการณ์ผลลัพธ์

สิ่งสำคัญคือต้องทราบว่าฟังก์ชันและคำสั่งที่แตกต่างกันจัดการกับสถานการณ์ที่ไม่มีผลลัพธ์แตกต่างกัน คำสั่ง PowerShell จำนวนมากส่งคืนค่าว่างที่นับได้และข้อผิดพลาดในสตรีมข้อผิดพลาด แต่คนอื่นก็มีข้อยกเว้นหรือให้ออบเจ็กต์สถานะแก่คุณ ยังคงขึ้นอยู่กับคุณที่จะทราบว่าคำสั่งที่คุณใช้จัดการกับผลลัพธ์ที่ไม่มีและสถานการณ์ข้อผิดพลาดอย่างไร

กำลังเริ่มต้นเป็น $null

นิสัยอย่างหนึ่งที่ฉันหยิบยกขึ้นมาคือการเริ่มต้นตัวแปรทั้งหมดของฉันก่อนที่จะใช้มัน คุณจะต้องดำเนินการนี้ในภาษาอื่น ที่ด้านบนสุดของฟังก์ชันหรือเมื่อฉันเข้าสู่ foreach loop ฉันจะกำหนดค่าทั้งหมดที่ฉันใช้

นี่คือสถานการณ์ที่ฉันต้องการให้คุณดูอย่างใกล้ชิด มันเป็นตัวอย่างของจุดบกพร่องที่ผมต้องไล่ตามก่อนหน้านี้

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
        }
    }
}

ความคาดหวังที่นี่คือ Get-Something ส่งคืนผลลัพธ์หรือค่าว่างที่นับได้ หากมีข้อผิดพลาดเราจะบันทึก จากนั้นเราตรวจสอบเพื่อให้แน่ใจว่าเราได้ผลลัพธ์ที่ถูกต้องก่อนที่จะประมวลผล

จุดบกพร่องที่ซ่อนอยู่ในโค้ดนี้คือเมื่อ Get-Something ส่งข้อยกเว้นและไม่ได้กำหนดค่าให้กับ $result มันล้มเหลวก่อนการกำหนด ดังนั้นเราจึงไม่กำหนด $null ให้กับตัวแปร $result ด้วยซ้ำ $result ยังคงมี $result ที่ถูกต้องก่อนหน้าจากการวนซ้ำอื่นๆ Update-Something เพื่อดำเนินการหลายครั้งบนวัตถุเดียวกันในตัวอย่างนี้

ฉันตั้งค่า $result เป็น $null ภายใน foreach loop ก่อนที่จะใช้เพื่อบรรเทาปัญหานี้

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

ปัญหาขอบเขต

นอกจากนี้ยังช่วยบรรเทาปัญหาการกำหนดขอบเขตด้วย ในตัวอย่างนี้ เรากำหนดค่าให้กับ $result ซ้ำไปซ้ำมาในลูป แต่เนื่องจาก PowerShell อนุญาตให้ค่าตัวแปรจากภายนอกฟังก์ชันตกเข้าสู่ขอบเขตของฟังก์ชันปัจจุบัน การเริ่มต้นค่าตัวแปรเหล่านั้นภายในฟังก์ชันของคุณจึงช่วยลดจุดบกพร่องที่สามารถนำมาใช้ในลักษณะนั้นได้

ตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้นในฟังก์ชันของคุณจะไม่ $null หากตั้งค่าเป็นค่าในขอบเขตหลัก ขอบเขตหลักอาจเป็นฟังก์ชันอื่นที่เรียกใช้ฟังก์ชันของคุณและใช้ชื่อตัวแปรเดียวกัน

หากฉันใช้ตัวอย่าง Do-something เดียวกันนั้นและลบการวนซ้ำ ฉันจะได้สิ่งที่ดูเหมือนตัวอย่างนี้:

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
    }
}

หากการเรียก Get-Something มีข้อยกเว้น การตรวจสอบ $null ของฉันจะค้นหา $result จาก Inrigger-Something รหัส>. การเริ่มต้นค่าภายในฟังก์ชันของคุณจะช่วยบรรเทาปัญหานี้ได้

การตั้งชื่อตัวแปรเป็นเรื่องยาก และเป็นเรื่องปกติที่ผู้เขียนจะใช้ชื่อตัวแปรเดียวกันในหลายฟังก์ชัน ฉันรู้ว่าฉันใช้ $node,$result,$data ตลอดเวลา ดังนั้นจึงเป็นเรื่องง่ายมากที่ค่าจากขอบเขตที่แตกต่างกันจะแสดงในตำแหน่งที่ไม่ควรปรากฏ

เปลี่ยนเส้นทางเอาต์พุตเป็น $null

ฉันได้พูดถึงค่า $null สำหรับบทความทั้งหมดนี้ แต่หัวข้อจะไม่สมบูรณ์หากฉันไม่ได้พูดถึงการเปลี่ยนเส้นทางเอาต์พุตไปที่ $null มีหลายครั้งที่คุณมีคำสั่งที่แสดงผลข้อมูลหรือออบเจ็กต์ที่คุณต้องการระงับ การเปลี่ยนเส้นทางเอาต์พุตไปที่ $null ทำเช่นนั้น

Out-Null

คำสั่ง Out-Null เป็นวิธีในตัวในการเปลี่ยนเส้นทางข้อมูลไปป์ไลน์ไปยัง $null

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

กำหนดให้ $null

คุณสามารถกำหนดผลลัพธ์ของคำสั่งเป็น $null เพื่อให้ได้ผลเช่นเดียวกับการใช้ Out-Null

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

เนื่องจาก $null เป็นค่าคงที่ คุณจึงไม่สามารถเขียนทับได้ ฉันไม่ชอบรูปลักษณ์ในโค้ดของฉัน แต่มักจะทำงานได้เร็วกว่า Out-Null

เปลี่ยนเส้นทางไปที่ $null

คุณยังสามารถใช้ตัวดำเนินการเปลี่ยนเส้นทางเพื่อส่งออกไปยัง $null

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

หากคุณกำลังจัดการกับไฟล์ปฏิบัติการบรรทัดคำสั่งที่ส่งออกไปยังสตรีมต่างๆ คุณสามารถเปลี่ยนเส้นทางสตรีมเอาต์พุตทั้งหมดไปที่ $null ดังนี้:

git status *> $null

สรุป

ฉันครอบคลุมเนื้อหาต่างๆ มากมายในบทความนี้ และฉันรู้ว่าบทความนี้มีการแยกส่วนมากกว่าการดำน้ำลึกส่วนใหญ่ของฉัน นั่นเป็นเพราะว่าค่า $null สามารถปรากฏขึ้นในที่ต่างๆ มากมายใน PowerShell และความแตกต่างทั้งหมดนั้นเฉพาะเจาะจงกับตำแหน่งที่คุณพบ ฉันหวังว่าคุณจะเดินออกไปจากสิ่งนี้ด้วยความเข้าใจที่ดีขึ้นเกี่ยวกับ $null และตระหนักถึงสถานการณ์ที่คลุมเครือมากขึ้นที่คุณอาจพบเจอ

บทความที่เกี่ยวข้อง