التعابير الاصطلاحيّة في لغة Kotlin

من موسوعة حسوب

تعرِض هذه الصفحة مجموعةً من التعابير الاصطلاحيّة المتعدِّدة والمستخدَمة بكثرةٍ في لغة Kotlin، وإن وُجد اصطلاحٌ غير مذكورٍ فيمكنك تعديل هذه الصفحة لإضافته.

إنشاء كائنات نقل البيانات DTO (كائنات POJO/POCO)

ليكن الصنف (class) الآتي باسم Customer:

data class Customer(val name: String, val email: String)

وله التوابع الوظيفية الآتية:

  • توابع getter (وتوابع setter في حالة المتحولات var) لكافة الخاصّيّات (properties)
  • equals()‎
  • hashCode()‎
  • toString()‎
  • copy()
  • component1()‎ و component2()‎ ...إلخ. وذلك لكافة الخاصّيّات (properties) (راجع أصناف البيانات data classes)

تحديد القيم الافتراضيّة لمتحوِّلات الدوال (function parameters)

fun foo(a: Int = 0, b: String = "") { ... }

ترشيح عناصر القائمة (filter)

val positives = list.filter { x -> x > 0 }

أو بشكلٍ أكثر اختصارًا:

val positives = list.filter { it > 0 }

ملء سلسلةٍ نصيَّة (string interpolation)

println("Name $name")

التحقُّق من القيمة باستخدام when

when (x) {
    is Foo -> ...
    is Bar -> ...
    else   -> ...
}

المرور بعناصر map أو قائمة من الثنائيات (pairs)

for ((k, v) in map) { println("$k -> $v") }

مهما كانت k أو v.

استخدام المجالات (ranges)

for (i in 1..100)       { ... } // المجال مغلق ويتضمن 100 قيمة 
for (i in 1 until 100)  { ... } // مجال نصف مفتوح ولا يشمل 100 قيمة 
for (x in 2..10 step 2) { ... } // مجال بخطوة ثابتة 2
for (x in 10 downTo 1)  { ... } // مجال تنازلي
if  (x in 1..10)        { ... } // قيمة المتحول هي إحدى القيم الواقعة في المجال من 1 حتى 10

قائمة للقراءة فقط

val list = listOf("a", "b", "c")

map للقراءة فقط

val map = mapOf("a" to 1, "b" to 2, "c" to 3)

الوصول إلى map

println(map["key"]) 
map["key"] = value

الخاصّيّة الكسولة (Lazy property)

val p: String by lazy {
    // عمليات على السلسلة النصيّة
}

الدوال الإضافية (Extension Functions)

fun String.spaceToCamelCase() { ... } 
"Convert this to camelcase".spaceToCamelCase()

إنشاء نمط singleton (المشترك)

object Resource {
    val name = "Name"
}

شيفرة if not null المختصرة

val files = File("Test").listFiles()
println(files?.size)

شيفرة if not و else المختصرة

val files = File("Test").listFiles()
println(files?.size ?: "empty")

تنفيذ التعليمة if null

val values = ...
val email = values["email"] ?: throw IllegalStateException("Email is missing!")

الحصول على العنصر الأول من مجموعة قد تكون خالية

val emails = ... // من الممكن أن تكون فارغة
val mainEmail = emails.firstOrNull() ?: ""

تنفيذ if not null

val value = ...
value?.let {
    ... // سينفذ هذا الجزء إن لم تكن القيمة null
}

تعيين map للقيم nullable إن لم تكن قيمتها null

val value = ...
val mapped = value?.let { transformValue(it) } ?: defaultValueIfValueIsNull

أمر العودة (return) في تعليمة when

fun transform(color: String): Int {

    return when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> throw 
IllegalArgumentException("Invalid color param value")
    }
}

تعبير try/catch

fun test() {

    val result = try {
        count()
    } catch (e: ArithmeticException) {
        throw IllegalStateException(e)
    }

    // العمل بالنتائج

}

تعبير if

fun foo(param: Int) {

    val result = if (param == 1) {
        "one"
    } else if (param == 2) {
        "two"
    } else {
        "three"
    }
}

استخدام الشكل البنائي للتوابع (methods) التي تعيد النوع Unit

fun arrayOfMinusOnes(size: Int): IntArray {
    return IntArray(size).apply { fill(-1) }
}

الدالة بتعبير وحيد

fun theAnswer() = 42

وهذا مماثل تمامًا للشكل:

fun theAnswer(): Int {
    return 42
}

ويمكن أن تُدمَج مع تعابير اصطلاحية أخرى مما ينتج شيفرة أقصر مثل دمجها مع تعبير when:

fun transform(color: String): Int = when (color) {
    "Red" -> 0
    "Green" -> 1
    "Blue" -> 2
    else -> throw 
IllegalArgumentException("Invalid color param value")
}

استدعاء عدة توابع (methods) عبر الكائن (object) (باستخدام with)

class Turtle {

    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

val myTurtle = Turtle()

with(myTurtle) { //لرسم مربع بمئة بكسل
    penDown()
    for(i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

تجربة Java 7 مع المصادر (resources)

val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
    println(reader.readText())
}

الشكل الملائم للدالة العامّة (generic) والتي تتطلَّب معلومات من نوع عامّ (generic)

//  public final class Gson {
//     ...
//     public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
//     ...

inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

استخدام القيم الثنائية (boolean) والتي قد تكون فارغة (nullable)

val b: Boolean? = ...
if (b == true) {
    ...
} else {
    //false أو null قيمة المتحول إما 
}

مصادر