Optional / Nullable — مفاهیم کلیدی و کار با انواع nullable

نویسنده: IT Sectr منتشر شده: 2026-05-26 زمان مطالعه: 8 دقیقه

Optional / Nullable — مکانیزم‌های زبان‌های Swift و Kotlin برای کار ایمن با عدم وجود مقدار. Optional در Swift و انواع nullable در Kotlin یک مشکل را حل می‌کنند — null reference — اما با رویکردهای نحوی و معنایی متفاوت. طبق داده‌های Swift.org, 2026، انواع اختیاری یک دسته کامل از خطاهای مرتبط با nil را حذف می‌کنند و بررسی null را به مرحله کامپایل منتقل می‌کنند.

نکات اصلی

  • Optional — نوع Swift، ارائه شده به صورت enum با دو case: some(Value) و none.
  • Nullable — در Kotlin با علامت سوال بعد از نوع مشخص می‌شود (String?)، و فراخوانی ایمن از طریق ?. انجام می‌شود.
  • Type safety — هر دو مکانیزم تضمین می‌کنند که مقادیر null به صورت صریح در مرحله کامپایل پردازش می‌شوند.
  • Unwrapping — Swift از if let، guard let و force unwrap (!) استفاده می‌کند. Kotlin — ?.، !! و عملگر elvis ?:.
  • Interop — Kotlin و Swift با پایگاه کد nullable از طریق حاشیه‌نویسی (annotations) و انواع ویژه (Implicitly Unwrapped Optional) تعامل می‌کنند.

Optional و Nullable چیست؟

Optional در Swift و nullable در Kotlin — ابزارهای زبانی هستند که null را بخش آشکار سیستم نوع می‌کنند. در Swift Optional یک enum است: Optional.none (nil) و Optional.some(Wrapped). در Kotlin nullable با پسوند ? در نوع مشخص می‌شود: String? می‌تواند رشته یا null باشد.

هر دو رویکرد مشکل اساسی را حل می‌کنند که تونی هور آن را «اشتباه میلیارد دلاری» نامید — null reference. قبل از ظهور انواع اختیاری، هر ارجاعی می‌توانست null باشد و بررسی به برنامه‌نویس واگذار می‌شد. Swift و Kotlin این بررسی را به مرحله کامپایل منتقل می‌کنند: کدی که null را نادیده می‌گیرد کامپایل نخواهد شد.

با وجود هدف مشترک، Swift و Kotlin null-safety را متفاوت پیاده‌سازی می‌کنند. Swift از نوع جبری Optional با pattern-matching کامل استفاده می‌کند. Kotlin nullable را در سطح کامپایلر در سیستم نوع تعبیه می‌کند، بدون ایجاد نوع wrapper جداگانه.

از نظر تاریخی، null reference در سال ۱۹۶۵ در زبان ALGOL W به عنوان راهی برای نمایش عدم وجود مقدار ظاهر شد. در طول شش دهه، null منبع بی‌شمار خرابی‌ها شده است — طبق تحقیقات تونی هور، ۳۰ تا ۵۰ درصد خطاها در کد production با NullPointerException مرتبط هستند. Swift با Optional و Kotlin با انواع nullable اولین زبان‌های主流 شدند که این مشکل را در سطح سیستم نوع حل کردند و null را بخش آشکار قرارداد تابع ساختند.

Optional در Swift: نحو و کار با انواع اختیاری

در Swift Optional یک نوع کامل است که به صورت enum Optional<Wrapped> اعلان شده است. شکر نحوی ? جایگزین نوشتار کامل می‌شود: Int? معادل Optional<Int> است. کار با Optional شامل چندین روش استخراج مقدار است.

If-let و guard-let binding

if let — استخراج شرطی: اگر Optional حاوی مقدار باشد، آن مقدار در داخل بلوک به یک ثابت متصل می‌شود. guard let — خروج زودهنگام از تابع اگر Optional برابر nil باشد. guard let کد را مسطح می‌کند و از if-let‌های تو در تو جلوگیری می‌کند.

Optional chaining

Optional chaining (دسترسی ایمن زنجیره‌ای) از طریق ? اجازه می‌دهد متد یا ویژگی را روی Optional بدون unwrapping صریح فراخوانی کنید. اگر هر حلقه از زنجیره nil باشد، کل زنجیره nil برمی‌گرداند. این کار کد را هنگام کار با داده‌های سلسله‌مراتبی کوتاه می‌کند.

عملگر Nil-coalescing

?? (nil-coalescing) — عملگری که مقدار Optional را برمی‌گرداند اگر nil نباشد، در غیر این صورت — مقدار پیش‌فرض. این یک جایگزین کوتاه برای if-let برای ارائه مقدار جایگزین است.

swift
var name: String? = "Alice"

// اتصال if-let
if let unwrapped = name {
    print("سلام، \(unwrapped)")
}

// Optional chaining
let count = name?.count

// Nil-coalescing
let display = name ?? "مهمان"

// Map روی Optional
let greeting = name.map { "Hello, \($0)" }

Nullable در Kotlin: فراخوانی‌های ایمن و عملگر elvis

در Kotlin nullable بخشی از سیستم نوع است، نه یک نوع wrapper جداگانه. نوع String? می‌تواند null داشته باشد، String (بدون علامت سوال) — هرگز. کامپایلر nullable را از طریق smart cast و حاشیه‌نویسی‌ها ردیابی می‌کند.

فراخوانی ایمن ?.

?. — عملگر فراخوانی ایمن. اگر شیء null نباشد، متد یا ویژگی فراخوانی می‌شود؛ اگر null باشد — null بدون فراخوانی برگردانده می‌شود. این معادل optional chaining در Swift است، اما از نظر نحوی کوتاه‌تر.

عملگر elvis ?:

?: — معادل Kotlin برای nil-coalescing. اگر عبارت سمت چپ null نباشد، برگردانده می‌شود؛ در غیر این صورت — مقدار سمت راست. عملگر elvis اغلب با خروج زودهنگام از طریق return یا throw ترکیب می‌شود.

Smart cast و عملگر !!

Smart cast — کامپایلر Kotlin به طور خودکار nullable را پس از بررسی null در if یا when به non-null تبدیل می‌کند. !! — فراخوانی اجباری (force unwrap) که در صورت null بودن NullPointerException پرتاب می‌کند. !! را فقط زمانی استفاده کنید که null یک باگ است.

kotlin
val name: String? = "Alice"

// فراخوانی ایمن
val length = name?.length

// عملگر elvis
val display = name ?: "مهمان"

// Smart cast پس از بررسی
if (name != null) {
    println("طول: ${name.length}")
}

// Let با لامبدا
name?.let { println("سلام، $it") }

// Force unwrap — فقط وقتی مطمئن هستید
val forced = name!!

Optional و Nullable: تفاوت‌های کلیدی رویکردها

اگرچه Swift و Kotlin یک任务 را حل می‌کنند، رویکردهای آنها به null-safety اساساً متفاوت است. درک این تفاوت‌ها برای توسعه‌دهندگانی که با هر دو پلتفرم کار می‌کنند مهم است.

نمایش در سیستم نوع

Swift از enum Optional — یک نوع جبری استاندارد استفاده می‌کند. Kotlin nullable را در سطح سیستم نوع کامپایلر تعبیه می‌کند، بدون ایجاد شیء wrapper. این بر عملکرد تأثیر می‌گذارد: Optional در Swift — یک شیء روی heap، nullable در Kotlin — بررسی null بدون تخصیص حافظه.

نحو و بیان

نحو Kotlin به لطف عملگرهای داخلی ?., ?:, !! کوتاه‌تر است. Swift نحو صریح بیشتری نیاز دارد: if let، guard let، map روی Optional. با این حال، Swift از طریق switch pattern-matching را فراهم می‌کند که Kotlin به طور مستقیم برای nullable پشتیبانی نمی‌کند.

سناریوSwiftKotlin
اعلانvar name: String?val name: String?
فراخوانی ایمنname?.countname?.length
مقدار پیش‌فرضname ?? "Guest"name ?: "مهمان"
استخراج شرطیif let x = namename?.let { x -> }
Force unwrapname!name!!

الگوهای null-safety در توسعه موبایل

در توسعه موبایل، الگوهای استانداردی برای کار با انواع اختیاری شکل گرفته است که مقدار کد قالبی را کاهش داده و امنیت را افزایش می‌دهد.

Map و flatMap روی Optional

Swift و Kotlin از map و flatMap برای Optional و nullable پشتیبانی می‌کنند. اگر مقدار وجود داشته باشد — تبدیل اعمال می‌شود، اگر null باشد — null برگردانده می‌شود. این کار بررسی‌های if-let تو در تو را حذف می‌کند.

مقادیر پیش‌فرض از طریق elvis

به جای if-let + else از ?: یا ?? با مقدار پیش‌فرض استفاده کنید. این کار کد را اعلامی می‌کند: «اگر X وجود دارد از آن استفاده کن، در غیر این صورت Y» به جای بررسی رویه‌ای.

Nullable در Compose و SwiftUI

در Jetpack Compose و SwiftUI انواع اختیاری نمایش را مدیریت می‌کنند: اگر حالت null باشد — کامپوننت را مخفی می‌کنیم، در غیر این صورت نمایش می‌دهیم. این با اصل single source of truth مطابقت دارد.

kotlin
data class UserState(
    val name: String?,
    val email: String?
)

// Smart cast در when با گزینه‌های مختلف
fun greeting(state: UserState): String = when {
    state.name != null && state.email != null ->
        "${state.name} (${state.email})"
    state.name != null -> state.name
    else -> "مهمان"
}

// Compose: نمایش بر اساس وجود
@Composable
fun UserProfile(name: String?) {
    name?.let {
        Text(text = it)
    } ?: Text(text = "داده‌ای موجود نیست")
}

برای مهاجرت کد Java موجود به Kotlin توصیه می‌شود از حاشیه‌نویسی‌های @Nullable و @NonNull از بسته androidx.annotation استفاده کنید. کامپایلر Kotlin این حاشیه‌نویسی‌ها را هنگام تعامل با Java در نظر می‌گیرد و به طور خودکار انواع مربوطه را nullable یا non-null می‌کند. مهاجرت تدریجی با حاشیه‌نویسی‌های صریح از فعال‌سازی سراسری null-safety در پروژه امن‌تر است.

اشتباهات رایج هنگام کار با Optional و Nullable

Null-safety تعداد خطاها را کاهش می‌دهد اما آنها را کاملاً حذف نمی‌کند. توسعه‌دهندگان اغلب هنگام کار با انواع اختیاری اشتباهات مشخصی مرتکب می‌شوند.

  • Force unwrap بدون تضمین — name! یا name!! بدون اطمینان از اینکه مقدار null نیست، منجر به crash در production می‌شود. قبل از force unwrap null را بررسی کنید.
  • if-let بیش از حد — if-let‌های تو در تو برای سه Optional یا بیشتر یک هرم (pyramid of doom) ایجاد می‌کند. از guard let یا flatMap استفاده کنید.
  • نادیده گرفتن nil-coalescing — بررسی صریح از طریق if-let با بلوک else با ?? یا ?: جایگزین می‌شود که کد را کوتاه‌تر و خوانایی را بهبود می‌بخشد.
  • Nullable در APIهای عمومی — اگر تابع nullable دریافت کند، هر فراخوانی نیاز به بررسی دارد. non-null را با مقدار پیش‌فرض یا overload ترجیح دهید.

سوالات متداول

Kotlin Nullable چه تفاوتی با Swift Optional دارد؟

Swift Optional — enum با case‌های some و none، شیء روی heap. Kotlin nullable — حاشیه‌نویسی در سیستم نوع که توسط کامپایلر بدون ایجاد wrapper بررسی می‌شود. Kotlin از نظر نحوی فشرده‌تر است، Swift در pattern-matching قدرتمندتر.

آیا Java null-safety دارد؟

Java null-safety داخلی ندارد. Optional (Java 8+) مشابه Swift Optional است، اما این یک wrapper با سربار است. حاشیه‌نویسی‌های @Nullable و @NonNull به تحلیلگر استاتیک کمک می‌کنند اما امنیت را تضمین نمی‌کنند.

چه زمانی به جای if-let از ?.let در Kotlin استفاده کنیم؟

?.let برای زنجیره عملیات مناسب است: اعمال تبدیل، ذخیره در دیتابیس، به‌روزرسانی UI — همه در یک بلوک. if با بررسی null برای شرایط پیچیده با چند متغیر nullable بهتر است.

Optional چگونه بر عملکرد تأثیر می‌گذارد؟

Swift Optional — enum با ذخیره‌سازی غیرمستقیم برای انواع بزرگ که می‌تواند باعث تخصیص حافظه شود. Kotlin nullable — بررسی null بدون هزینه اضافی. برای مسیرهای داغ (recycler view، انیمیشن‌ها) Kotlin کارآمدتر است.

آیا برای فیلدهای data class باید از nullable استفاده کرد؟

فقط زمانی از nullable استفاده کنید که فیلد واقعاً می‌تواند وجود نداشته باشد: داده‌های اختیاری پروفایل، تنظیمات غیراجباری. اگر فیلد همیشه پر است — از non-null با مقدار پیش‌فرض از طریق عملگر elvis در زمان ایجاد استفاده کنید.

خلاصه

  • Optional (Swift) و Nullable (Kotlin) — مکانیزم‌های زبانی که پردازش null را به مرحله کامپایل منتقل کرده و از NPE جلوگیری می‌کنند.
  • Swift Optional — enum با دو case که pattern-matching و map/flatMap را فراهم می‌کند. Kotlin nullable — بخشی از سیستم نوع با عملگرهای فشرده ?., ?:, !!.
  • Optional chaining (Swift ?.) و فراخوانی ایمن (Kotlin ?.) امکان کار با داده‌های سلسله‌مراتبی را بدون بررسی‌های تو در تو فراهم می‌کنند.
  • Nil-coalescing (??) و عملگر elvis (?:) مقادیر پیش‌فرض را بدون شاخه‌های if-else صریح فراهم می‌کنند.
  • Smart cast در Kotlin به طور خودکار nullable را پس از بررسی به non-null تبدیل می‌کند و تعداد تبدیل‌های صریح را کاهش می‌دهد.
  • از force unwrap (! / !!) در production، if-let‌های بیش از حد و انواع nullable در APIهای عمومی بدون نیاز خودداری کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید