Optional / Nullable — مکانیزمهای زبانهای Swift و Kotlin برای کار ایمن با عدم وجود مقدار. Optional در Swift و انواع nullable در Kotlin یک مشکل را حل میکنند — null reference — اما با رویکردهای نحوی و معنایی متفاوت. طبق دادههای Swift.org, 2026، انواع اختیاری یک دسته کامل از خطاهای مرتبط با nil را حذف میکنند و بررسی null را به مرحله کامپایل منتقل میکنند.
نکات اصلی
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 را بخش آشکار قرارداد تابع ساختند.
در Swift Optional یک نوع کامل است که به صورت enum Optional<Wrapped> اعلان شده است. شکر نحوی ? جایگزین نوشتار کامل میشود: Int? معادل Optional<Int> است. کار با Optional شامل چندین روش استخراج مقدار است.
if let — استخراج شرطی: اگر Optional حاوی مقدار باشد، آن مقدار در داخل بلوک به یک ثابت متصل میشود. guard let — خروج زودهنگام از تابع اگر Optional برابر nil باشد. guard let کد را مسطح میکند و از if-letهای تو در تو جلوگیری میکند.
Optional chaining (دسترسی ایمن زنجیرهای) از طریق ? اجازه میدهد متد یا ویژگی را روی Optional بدون unwrapping صریح فراخوانی کنید. اگر هر حلقه از زنجیره nil باشد، کل زنجیره nil برمیگرداند. این کار کد را هنگام کار با دادههای سلسلهمراتبی کوتاه میکند.
?? (nil-coalescing) — عملگری که مقدار Optional را برمیگرداند اگر nil نباشد، در غیر این صورت — مقدار پیشفرض. این یک جایگزین کوتاه برای if-let برای ارائه مقدار جایگزین است.
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)" }
در Kotlin nullable بخشی از سیستم نوع است، نه یک نوع wrapper جداگانه. نوع String? میتواند null داشته باشد، String (بدون علامت سوال) — هرگز. کامپایلر nullable را از طریق smart cast و حاشیهنویسیها ردیابی میکند.
?. — عملگر فراخوانی ایمن. اگر شیء null نباشد، متد یا ویژگی فراخوانی میشود؛ اگر null باشد — null بدون فراخوانی برگردانده میشود. این معادل optional chaining در Swift است، اما از نظر نحوی کوتاهتر.
?: — معادل Kotlin برای nil-coalescing. اگر عبارت سمت چپ null نباشد، برگردانده میشود؛ در غیر این صورت — مقدار سمت راست. عملگر elvis اغلب با خروج زودهنگام از طریق return یا throw ترکیب میشود.
Smart cast — کامپایلر Kotlin به طور خودکار nullable را پس از بررسی null در if یا when به non-null تبدیل میکند. !! — فراخوانی اجباری (force unwrap) که در صورت null بودن NullPointerException پرتاب میکند. !! را فقط زمانی استفاده کنید که null یک باگ است.
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!!
اگرچه 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 پشتیبانی نمیکند.
| سناریو | Swift | Kotlin |
|---|---|---|
| اعلان | var name: String? | val name: String? |
| فراخوانی ایمن | name?.count | name?.length |
| مقدار پیشفرض | name ?? "Guest" | name ?: "مهمان" |
| استخراج شرطی | if let x = name | name?.let { x -> } |
| Force unwrap | name! | name!! |
در توسعه موبایل، الگوهای استانداردی برای کار با انواع اختیاری شکل گرفته است که مقدار کد قالبی را کاهش داده و امنیت را افزایش میدهد.
Swift و Kotlin از map و flatMap برای Optional و nullable پشتیبانی میکنند. اگر مقدار وجود داشته باشد — تبدیل اعمال میشود، اگر null باشد — null برگردانده میشود. این کار بررسیهای if-let تو در تو را حذف میکند.
به جای if-let + else از ?: یا ?? با مقدار پیشفرض استفاده کنید. این کار کد را اعلامی میکند: «اگر X وجود دارد از آن استفاده کن، در غیر این صورت Y» به جای بررسی رویهای.
در Jetpack Compose و SwiftUI انواع اختیاری نمایش را مدیریت میکنند: اگر حالت null باشد — کامپوننت را مخفی میکنیم، در غیر این صورت نمایش میدهیم. این با اصل single source of truth مطابقت دارد.
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 در پروژه امنتر است.
Null-safety تعداد خطاها را کاهش میدهد اما آنها را کاملاً حذف نمیکند. توسعهدهندگان اغلب هنگام کار با انواع اختیاری اشتباهات مشخصی مرتکب میشوند.
سوالات متداول
Swift Optional — enum با caseهای some و none، شیء روی heap. Kotlin nullable — حاشیهنویسی در سیستم نوع که توسط کامپایلر بدون ایجاد wrapper بررسی میشود. Kotlin از نظر نحوی فشردهتر است، Swift در pattern-matching قدرتمندتر.
Java null-safety داخلی ندارد. Optional (Java 8+) مشابه Swift Optional است، اما این یک wrapper با سربار است. حاشیهنویسیهای @Nullable و @NonNull به تحلیلگر استاتیک کمک میکنند اما امنیت را تضمین نمیکنند.
?.let برای زنجیره عملیات مناسب است: اعمال تبدیل، ذخیره در دیتابیس، بهروزرسانی UI — همه در یک بلوک. if با بررسی null برای شرایط پیچیده با چند متغیر nullable بهتر است.
Swift Optional — enum با ذخیرهسازی غیرمستقیم برای انواع بزرگ که میتواند باعث تخصیص حافظه شود. Kotlin nullable — بررسی null بدون هزینه اضافی. برای مسیرهای داغ (recycler view، انیمیشنها) Kotlin کارآمدتر است.
فقط زمانی از nullable استفاده کنید که فیلد واقعاً میتواند وجود نداشته باشد: دادههای اختیاری پروفایل، تنظیمات غیراجباری. اگر فیلد همیشه پر است — از non-null با مقدار پیشفرض از طریق عملگر elvis در زمان ایجاد استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید