12

Lambda، Higher-Order و Extension؛ ادویه‌های حرفه‌ای

اینجا کدت کم‌کم از «کار می‌کنه» می‌رسه به «خوشگل هم کار می‌کنه».

درس 12 از 20

Lambda یعنی تابع کوچولوی بی‌اسم

لامبدا برای وقتی عالیه که یه رفتار کوچیک رو همون‌جا تعریف می‌کنی. مثلاً برای filter و map. اسم نمی‌خواد؛ مثل مهمون ناخوانده میاد کارشو می‌کنه می‌ره.

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

lambda
val numbers = listOf(1, 2, 3, 4)
val doubled = numbers.map { number -> number * 2 }
println(doubled)
خروجی یا نتیجه اجرا
[2, 4, 6, 8]
نکته کاربردی: این بخش اسکلت ذهنی درس را می‌سازد. وقتی بدانی این قطعه دقیقاً چه مسئله‌ای را حل می‌کند، بعداً موقع پروژه فقط syntax حفظی تحویل نمی‌دهی؛ تصمیم درست می‌گیری. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

Higher-order function

تابعی که تابع بگیره یا تابع برگردونه، higher-order حساب می‌شه. این ستون فقرات خیلی از APIهای کاتلین و Composeه.

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

تابع مرتبه‌بالا
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

fun main() {
    val result = calculate(4, 5) { x, y -> x + y }
    println(result)
}
خروجی یا نتیجه اجرا
9
نکته کاربردی: اینجا باید به رفتار کد نگاه کنی، نه فقط ظاهرش. مقدارها را عوض کن و دوباره اجرا بگیر تا دستت بفهمد برنامه چطور واکنش نشان می‌دهد. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

Extension function

با extension می‌تونی به یک نوع موجود، تابع اضافه کنی بدون اینکه کلاس اصلی رو دستکاری کنی. مثل اینکه به ماشینت اسپویلر بزنی، بدون اینکه کارخانه رو بخری.

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

extension
fun String.toFriendlyTitle(): String {
    return trim().replaceFirstChar { it.uppercase() }
}

fun main() {
    println(" kotlin ".toFriendlyTitle())
}
خروجی یا نتیجه اجرا
Kotlin
نکته کاربردی: این الگو در پروژه واقعی زیاد تکرار می‌شود. از همین حالا تمیز و خوانا بنویس تا بعداً موقع دیباگ، خودت به خودت فحش ندهی. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

Scope functions

`let`, `run`, `with`, `apply`, `also` برای کارهای تمیز با آبجکت‌ها هستن. زیاد استفاده کنی کدت جادویی و گیج‌کننده می‌شه؛ اندازه نگه دار.

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

apply
data class User(var name: String = "", var age: Int = 0)

val user = User().apply {
    name = "Mina"
    age = 25
}
خروجی یا نتیجه اجرا
User(name=Mina, age=25)
نکته کاربردی: نکته حرفه‌ای این است که Kotlin معمولاً راه کوتاه‌تر دارد، ولی کوتاه‌تر همیشه بهتر نیست. اول خوانایی، بعد زرنگ‌بازی. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

نتیجه این درس 🎯

Lambda، higher-order و extension باعث می‌شوند Kotlin خوش‌دست و خوش‌خوان شود. ولی زیاده‌روی نکن؛ هدف تمیز شدن کد است، نه شعبده‌بازی.

تمرین! 🧠

یک extension function برای Int بنویس که بگوید عدد زوج است یا نه.

جواب تمرین
fun Int.isEven(): Boolean = this % 2 == 0

fun main() {
    println(10.isEven())
    println(7.isEven())
}
خروجی جواب
true
false