تخطَّ إلى المحتوى

المتغيرات وأنواع البيانات في Kotlin

الدرس 2 من 11 · Kotlin

في الدرس الأول ألقيت نظرة سريعة على val و var. الآن سنتعمق في المتغيرات وأنواع البيانات في Kotlin، لأنها الأساس الذي يقوم عليه كل تطبيق أندرويد ستكتبه. وستكتشف ميزة تجعل Kotlin محبوبة جداً: حمايتك من أخطاء القيم الفارغة.

fun main() {
val name = "سارة"
var points = 10
points = points + 5
println("$name لديها $points نقطة")
}
الناتج
سارة لديها 15 نقطة
  • val (من value): قيمة لا يمكن إعادة إسنادها بعد تعريفها. مثل اسمك في شهادة الميلاد.
  • var (من variable): متغير يمكن تغيير قيمته. مثل رصيد نقاطك في لعبة.

لو كتبت name = "منى" سيرفض المترجم الكود قبل التشغيل بخطأ 'val' cannot be reassigned.

Kotlin لغة ثابتة الأنواع: لكل متغير نوع محدد لا يتغير. يمكنك كتابة النوع صراحة بعد نقطتين:

val city: String = "القاهرة"
val students: Int = 30
val price: Double = 12.5
val isOpen: Boolean = true
val grade: Char = 'A'
النوع يخزن مثال
Int أعداد صحيحة 30
Long أعداد صحيحة كبيرة جداً 7_000_000_000
Double أعداد عشرية 12.5
Boolean صح أو خطأ true و false
Char حرف واحد بين علامتين مفردتين 'A'
String نص بين علامتين مزدوجتين "مرحباً"

لاحظ أن كل الأنواع تبدأ بحرف كبير. والشرطة السفلية في 7_000_000_000 لتسهيل القراءة فقط، ولا تغيّر القيمة.

في الأغلب لا تحتاج كتابة النوع، لأن Kotlin تستنتجه من القيمة: val price = 12.5 تعرف وحدها أنه Double. لكن بعد الاستنتاج، النوع ثابت: لا تستطيع أن تضع نصاً في متغير من نوع Int.

println(10 / 4)
println(10.0 / 4)
println(10 % 4)
الناتج
2
2.5
2

انتبه للسطر الأول: قسمة عددين صحيحين تعطي عدداً صحيحاً، ويُحذف الكسر. إذا أردت النتيجة العشرية، اجعل أحد الطرفين عشرياً مثل 10.0. والعامل % يعطي باقي القسمة.

لوضع قيمة متغير داخل نص، استخدم $، وللتعبيرات استخدم ${...}:

val first = "أحمد"
println("طول الاسم: ${first.length}")
println("بعد المكافأة: ${points + 3}")
الناتج
طول الاسم: 4
بعد المكافأة: 18

هذه الميزة اسمها قوالب النصوص (String Templates)، وهي أوضح بكثير من دمج النصوص بعلامة +.

Kotlin لا تحوّل الأنواع تلقائياً، بل تطلب منك التحويل صراحة:

val input = "25"
val n = input.toInt()
println(n + 5)
println("2.5".toDouble() * 2)
println(42.toString() + "!")
println("abc".toIntOrNull())
الناتج
30
5.0
42!
null
  • toInt() و toDouble(): من نص إلى رقم. إذا لم يكن النص رقماً، يتوقف البرنامج بخطأ.
  • toIntOrNull(): النسخة الآمنة، تُرجع null بدلاً من الخطأ.
  • toString(): من أي قيمة إلى نص.

null تعني «لا قيمة». وفي Kotlin، المتغير العادي لا يقبل null أبداً. إذا كانت القيمة قد تكون غير موجودة، أضف ? بعد النوع:

var nickname: String? = null
println(nickname?.length)
println(nickname ?: "لا يوجد")
nickname = "سوسو"
println(nickname?.length)
الناتج
null
لا يوجد
4
  • String?: نص أو null.
  • ?. (الوصول الآمن): «إذا كانت القيمة موجودة أعطني طولها، وإلا أعطني null بهدوء».
  • ?: (يسمى معامل إلفيس Elvis): «إذا كانت null، فاستخدم هذه القيمة البديلة».

هذه الميزة تمنع واحداً من أشهر أسباب انهيار تطبيقات أندرويد القديمة المكتوبة بـ Java، وهو خطأ NullPointerException.

اكتب برنامجاً لفاتورة صغيرة:

fun main() {
val productName = "سماعة"
val unitPrice = 150.0
val quantity = 2
val total = unitPrice * quantity
println("المنتج: $productName")
println("الإجمالي: $total جنيه")
}
الناتج المتوقع
المنتج: سماعة
الإجمالي: 300.0 جنيه

تحدٍّ: أضف متغيراً لكود الخصم من نوع String? قيمته null، واطبع «لا يوجد خصم» باستخدام ?:.

  • إعادة إسناد val: خطأ 'val' cannot be reassigned. استخدم var إذا كانت القيمة تتغير فعلاً.
  • نسيان التحويل: "25" + 5 تعطي النص "255" وليس 30! حوّل أولاً بـ toInt().
  • قسمة الأعداد الصحيحة: 7 / 2 تعطي 3 وليس 3.5. استخدم 7.0 / 2.

سؤال

ما ناتج println(9 / 2) في Kotlin؟

سؤال

ماذا يطبع val city: String? = null; println(city ?: "غير محدد")؟

  • val لقيمة لا يُعاد إسنادها، و var لمتغير يتغير، وفضّل val دائماً.
  • الأنواع الأساسية: Int و Long و Double و Boolean و Char و String.
  • Kotlin تستنتج النوع، لكنه يبقى ثابتاً بعد ذلك.
  • $name و ${...} لقوالب النصوص، و toInt() و toIntOrNull() للتحويل.
  • String? يقبل null، و ?. للوصول الآمن، و ?: للقيمة البديلة.