پو

پوچی در Julia

1 تمرین

درباره‌ی پوچی

بسیاری از زبان‌ها روشی مانند null یا none دارند تا مقداری را که وجود ندارد نشان دهند. چون Julia برای کار با حجم زیادی از داده‌ها (که اغلب نامرتب هستند) طراحی شده است، چندین شکل مختلف از نیستی دارد.

هدف کلی این است که هر جا با مقدار گمشده یا مشکوکی روبه‌رو شدیم آن را علامت‌گذاری کنیم و سپس بدون پرتاب استثنا ادامه دهیم.

nothing

اگر مقداری واقعاً وجود نداشته باشد، با nothing نشان داده می‌شود. این احتمالاً به آنچه C (با NULL) یا Python (با None) انجام می‌دهند نزدیک‌تر است.

julia> n = nothing

julia> isnothing(n)
true

julia> typeof(n)
Nothing

بنابراین nothing مقداری یگانه از نوع Nothing است و می‌توانیم آن را بررسی کنیم.

یکی از کاربردهای رایج nothing، استفاده از آن به‌عنوان مقدار بازگشتی (یا نبودِ مقدار) برای توابعی است که فقط برای عوارض جانبی‌شان به کار می‌روند (چاپ کردن، پیکربندی شبکه و از این قبیل).

missing

برای موقعیت‌هایی که یک مقدار در تئوری وجود دارد اما نمی‌دانیم چیست، از missing استفاده می‌شود. برای مثال، هنگام شمارش خودروهایی که در جاده‌ای در حال حرکت‌اند، ممکن است ناظران انسانی به استراحت نیاز داشته باشند یا حسگرهای خودکار از کار بیفتند، اما ترافیک همچنان در جریان است.

بنابراین missing یک جانگهدار است که به انسان‌ها هشدار می‌دهد باید تصمیم بگیرند با این شکاف در داده‌ها چطور رفتار کنند.

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> typeof(mv)
Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})

julia> ismissing.(mv)  # broadcast function, displays as 1 for true, 0 for false
3-element BitVector:
 0
 0
 1

زبان‌های کمی این قابلیت را به‌صورت داخلی دارند، اما معادل‌های نزدیک آن NA در R یا NULL در SQL است.

نوع بردار در مثال بالا Union{Missing, Int64} تعیین شده است که شباهت‌هایی به نوع‌هایی مانند Option یا Maybe در زبان‌های دیگر دارد.

اگر مقادیر missing وجود داشته باشند، عبارات معمولاً به‌صورت پیش‌فرض missing برمی‌گردانند. اگر می‌خواهید این مقادیر نادیده گرفته شوند، از تابع skipmissing() استفاده کنید تا این موضوع را به‌صراحت بیان کنید:

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> sum(mv)  # missing in, missing out
missing

julia> skipmissing(mv)
skipmissing(Union{Missing, Int64}[1, 2, missing])

julia> collect(skipmissing(mv))
2-element Vector{Int64}:
 1
 2

julia> sum(skipmissing(mv))  # functions like sum() can work with iterators
3

چون skipmissing یک تکرارگر می‌سازد، اگر به یک بردار نیاز دارید آن را در collect() بپیچید.

گاهی جایگزین کردن مقادیر missing با یک مقدار پیش‌فرض مفید است. ماکروی @coalesce() برای این کار به کار می‌آید، چون اولین مقدار غیرِ missing را برمی‌گرداند (یا اگر مقدار دیگری نباشد، missing را).

julia> str = ["I", "exist", missing]
3-element Vector{Union{Missing, String}}:
 "I"
 "exist"
 missing

julia> [@coalesce(s, "-") for  s in str]
3-element Vector{String}:
 "I"
 "exist"
 "-"

NaN

NaN که مخفف «Not a Number» است، در موقعیت‌هایی که انتظار یک عدد می‌رود، مشکلی در محاسبه را علامت‌گذاری می‌کند.

julia> v = [0, 1, -1]
3-element Vector{Int64}:
  0
  1
 -1

julia> v / 0
3-element Vector{Float64}:
 NaN
  Inf
 -Inf
 
julia> sum(v / 0)
NaN

هر محاسبه‌ای روی داده‌ای که شامل NaN باشد، نتیجه‌ای NaN می‌دهد.

در حال حاضر تابع ویژه‌ای برای حذف مقادیر NaN وجود ندارد، اما تابع استاندارد filter() این کار را به‌سادگی انجام می‌دهد. فقط مقادیری که شرط داده‌شده برای آن‌ها true باشد، در آرایه‌ی نتیجه کپی می‌شوند:

julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
 1.0
 2.0

داده‌های تعریف‌نشده

این مورد احتمالاً کمتر به کارتان می‌آید. موارد استثنایی عبارت‌اند از:

  • راه‌هایی برای ساختن انواع ترکیبی (مانند struct) با فیلدهای مقداردهی‌نشده وجود دارد. Julia معمولاً تلاش می‌کند از مقادیر پیش‌فرض استفاده کند، اما این کار فقط وقتی ممکن است که اطلاعات کافی برای استنتاج نوع فیلد داشته باشد.
  • در برخی موارد، مقداردهی اولیه‌ی یک بردار به‌صورت undef می‌تواند روشی انعطاف‌پذیر و کارآمد باشد. برای مثال، این روش در راه‌حل‌های جامعه برای تمرین بافر حلقوی به کار رفته است (تکنیکی پیشرفته، اما این تمرین در سطح سخت دسته‌بندی می‌شود).

گرفتن نتیجه‌ی undef از تلاش برای دسترسی به یک مقدار، یک وضعیت خطاست که معمولاً با UndefRefError علامت‌گذاری می‌شود.

ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

پوچی را یاد بگیرید