ทุกสิ่งที่คุณอยากรู้เกี่ยวกับ $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 และตระหนักถึงสถานการณ์ที่คลุมเครือมากขึ้นที่คุณอาจพบเจอ