الفرق بين المراجعتين لصفحة: «Kotlin/basic syntax»
طلا ملخص تعديل |
لا ملخص تعديل |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:البنية العامّة للغة Kotlin}}</noinclude> | <noinclude>{{DISPLAYTITLE:البنية العامّة للغة Kotlin}}</noinclude> | ||
== | ==تعريف الحزمة (Package)== | ||
يُكتب توصيف الحزمة (package) في بداية الملف المصدريّ (source file) بالشكل الآتي:<syntaxhighlight lang="kotlin"> | يُكتب توصيف الحزمة (package) في بداية الملف المصدريّ (source file) بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
package my.demo | package my.demo | ||
import java.util.* | import java.util.* | ||
// ... | // ... | ||
</syntaxhighlight>ولا يُشترط التوافق ما بين الحزمة (package) والمجلد الموجودة فيه (directory)، إذ من الممكن أن تتوضع الملفات المصدريّة عشوائيًّا في نظام الملفات. | </syntaxhighlight>ولا يُشترط التوافق ما بين الحزمة (package) والمجلد الموجودة فيه (directory)، إذ من الممكن أن تتوضع الملفات المصدريّة عشوائيًّا في نظام الملفات. | ||
المزيد عن [[الحزم packages]]. | المزيد عن [[Kotlin/packages|الحزم packages]]. | ||
==تعريف الدالة (Function)== | ==تعريف الدالة (Function)== | ||
إن كانت الدالة بمتحولين من نوع Int وتعيد قيمةً بنوع Int أيضًا، يصبح تعريفها بالشكل:<syntaxhighlight lang="kotlin"> | إن كانت الدالة بمتحولين من نوع Int وتعيد قيمةً بنوع Int أيضًا، يصبح تعريفها بالشكل:<syntaxhighlight lang="kotlin"> | ||
fun sum(a: Int, b: Int): Int { | fun sum(a: Int, b: Int): Int { | ||
return a + b | return a + b | ||
} | } | ||
سطر 25: | سطر 21: | ||
</syntaxhighlight>وإن لم تُعد الدالة أية قيمةٍ بمعنىً يصبح تعريفها على النحو الآتي: (الحالة الافتراضية هي Unit)<syntaxhighlight lang="kotlin"> | </syntaxhighlight>وإن لم تُعد الدالة أية قيمةٍ بمعنىً يصبح تعريفها على النحو الآتي: (الحالة الافتراضية هي Unit)<syntaxhighlight lang="kotlin"> | ||
fun printSum(a: Int, b: Int): Unit { | fun printSum(a: Int, b: Int): Unit { | ||
println("sum of $a and $b is ${a + b}") | println("sum of $a and $b is ${a + b}") | ||
} | } | ||
سطر 33: | سطر 27: | ||
</syntaxhighlight>ويمكن الاستغناء عن النوع المُعاد Unit ليصبح التعريف بالشكل:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>ويمكن الاستغناء عن النوع المُعاد Unit ليصبح التعريف بالشكل:<syntaxhighlight lang="kotlin"> | ||
fun printSum(a: Int, b: Int) { | fun printSum(a: Int, b: Int) { | ||
println("sum of $a and $b is ${a + b}") | println("sum of $a and $b is ${a + b}") | ||
} | } | ||
</syntaxhighlight>المزيد عن [[الدوال functions]]. | </syntaxhighlight>المزيد عن [[Kotlin/functions|الدوال functions]]. | ||
==تعريف المتحولات (Variables)== | ==تعريف المتحولات (Variables)== | ||
لتعريف متحوِّلٍ محليٍّ بإسنادٍ وحيد (للقراءة فقط ولا يمكن إعطاؤه قيمةً جديدة) تُستخدَم إحدى الصيغ الآتية:<syntaxhighlight lang="kotlin"> | لتعريف متحوِّلٍ محليٍّ بإسنادٍ وحيد (للقراءة فقط ولا يمكن إعطاؤه قيمةً جديدة) تُستخدَم إحدى الصيغ الآتية:<syntaxhighlight lang="kotlin"> | ||
سطر 59: | سطر 51: | ||
</syntaxhighlight>وقد تكون المتحولات واقعةً بمستوىً أعلى من البنية الحاليّة كما في المثال الآتي: (المتحولان PI و x يقعان في مستوى أعلى من الدالة incrementX)<syntaxhighlight lang="kotlin"> | </syntaxhighlight>وقد تكون المتحولات واقعةً بمستوىً أعلى من البنية الحاليّة كما في المثال الآتي: (المتحولان PI و x يقعان في مستوى أعلى من الدالة incrementX)<syntaxhighlight lang="kotlin"> | ||
val PI = 3.14 | val PI = 3.14 | ||
var x = 0 | var x = 0 | ||
fun incrementX() { | fun incrementX() { | ||
x += 1 | x += 1 | ||
} | } | ||
</syntaxhighlight>المزيد عن [[الخاصّيات properties والحقول fields]]. | </syntaxhighlight>المزيد عن [[Kotlin/properties|الخاصّيات properties والحقول fields]]. | ||
==التعليقات (Comments)== | ==التعليقات (Comments)== | ||
تدعم لغة Kotlin نوعين من التعليقات (كما هو الحال في لغتَي Java و JavaScript)؛ وهما التعليقات السطريّة أو التعليقات بأكثر من سطر، وتكون صياغتهما بالشكل الآتي:<syntaxhighlight lang="kotlin"> | تدعم لغة Kotlin نوعين من التعليقات (كما هو الحال في لغتَي Java و JavaScript)؛ وهما التعليقات السطريّة أو التعليقات بأكثر من سطر، وتكون صياغتهما بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
سطر 75: | سطر 64: | ||
/* هذا التعليق | /* هذا التعليق | ||
بأكثر من سطر */ | بأكثر من سطر */ | ||
سطر 85: | سطر 73: | ||
تكون صياغتها بالشكل الآتي:<syntaxhighlight lang="kotlin"> | تكون صياغتها بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
var a = 1 | var a = 1 | ||
// اسم بسيط ضمن قالب نصيّ | // اسم بسيط ضمن قالب نصيّ | ||
val s1 = "a is $a" | val s1 = "a is $a" | ||
a = 2 | a = 2 | ||
// تعبيرٌ عشوائيّ ضمن قالب نصيّ | // تعبيرٌ عشوائيّ ضمن قالب نصيّ | ||
val s2 = "${s1.replace("is", "was")}, but now is $a" | val s2 = "${s1.replace("is", "was")}, but now is $a" | ||
</syntaxhighlight>المزيد عن [[قوالب السلاسل النصية]]. | </syntaxhighlight>المزيد عن [[Basic types|قوالب السلاسل النصية]]. | ||
==استخدام التعابير الشرطية (Conditional Expressions)== | ==استخدام التعابير الشرطية (Conditional Expressions)== | ||
توضِّح الدالة الآتية (لإعادة القيمة الأكبر من بين القيمتين a و b) طريقة صياغة الشرط if:<syntaxhighlight lang="kotlin"> | توضِّح الدالة الآتية (لإعادة القيمة الأكبر من بين القيمتين a و b) طريقة صياغة الشرط if:<syntaxhighlight lang="kotlin"> | ||
fun maxOf(a: Int, b: Int): Int { | fun maxOf(a: Int, b: Int): Int { | ||
if (a > b) { | if (a > b) { | ||
return a | return a | ||
} else { | } else { | ||
return b | return b | ||
} | } | ||
} | } | ||
سطر 117: | سطر 95: | ||
</syntaxhighlight>وكما يمكن استخدام الشرط if بصياغة تعبيريّة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>وكما يمكن استخدام الشرط if بصياغة تعبيريّة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
fun maxOf(a: Int, b: Int) = if (a > b) a else b | fun maxOf(a: Int, b: Int) = if (a > b) a else b | ||
</syntaxhighlight>المزيد عن استخدام [[الشرط if]]. | </syntaxhighlight>المزيد عن استخدام [[Kotlin/control flow if|الشرط if]]. | ||
==استخدام القيم التي تقبل القيمة الفارغة Null والتحقُّق منها== | ==استخدام القيم التي تقبل القيمة الفارغة Null والتحقُّق منها== | ||
عندما تكون القيمة null محتملة للمتحول المرجعي (reference) فيُقال عنه أنه nullable. | عندما تكون القيمة null محتملة للمتحول المرجعي (reference) فيُقال عنه أنه nullable. | ||
سطر 123: | سطر 101: | ||
إن الدالة الآتية ستعيد قيمة null إن لم تحتوي السلسلة str على قيمةٍ صحيحة:<syntaxhighlight lang="kotlin"> | إن الدالة الآتية ستعيد قيمة null إن لم تحتوي السلسلة str على قيمةٍ صحيحة:<syntaxhighlight lang="kotlin"> | ||
fun parseInt(str: String): Int? { | fun parseInt(str: String): Int? { | ||
// ... | // ... | ||
} | } | ||
سطر 131: | سطر 107: | ||
</syntaxhighlight>أما الدالة الآتية (إخراج قيمة ناتج جداء العددين الموجودين بالسلسلتين arg1 و arg2) فتعيد قيمة null:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أما الدالة الآتية (إخراج قيمة ناتج جداء العددين الموجودين بالسلسلتين arg1 و arg2) فتعيد قيمة null:<syntaxhighlight lang="kotlin"> | ||
fun printProduct(arg1: String, arg2: String) { | fun printProduct(arg1: String, arg2: String) { | ||
val x = parseInt(arg1) // تحويل السلسلة النصيّة إلى قيمة عددية تُخزّن في المتحول | val x = parseInt(arg1) // تحويل السلسلة النصيّة إلى قيمة عددية تُخزّن في المتحول | ||
val y = parseInt(arg2) | val y = parseInt(arg2) | ||
// قد ينتج عن عملية الجداء حدوث خطأ في حال احتواء أحد المتحولين على قيمة null | // قد ينتج عن عملية الجداء حدوث خطأ في حال احتواء أحد المتحولين على قيمة null | ||
if (x != null && y != null) { | if (x != null && y != null) { | ||
println(x * y) | println(x * y) | ||
} | } | ||
else { | else { | ||
println("either '$arg1' or '$arg2' is not a number") | println("either '$arg1' or '$arg2' is not a number") | ||
} | } | ||
} | } | ||
سطر 155: | سطر 123: | ||
</syntaxhighlight>أو بالشكل:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أو بالشكل:<syntaxhighlight lang="kotlin"> | ||
// ... | // ... | ||
if (x == null) { | if (x == null) { | ||
println("Wrong number format in arg1: '$arg1'") | println("Wrong number format in arg1: '$arg1'") | ||
return | return | ||
} | } | ||
if (y == null) { | if (y == null) { | ||
println("Wrong number format in arg2: '$arg2'") | println("Wrong number format in arg2: '$arg2'") | ||
return | return | ||
} | } | ||
سطر 175: | سطر 136: | ||
</syntaxhighlight>المزيد عن [[القيمة الفارغة null]]. | </syntaxhighlight>المزيد عن [[Kotlin/null safety|القيمة الفارغة null]]. | ||
==التحقُّق من النوع والتحويلات التلقائية بين الأنواع (Casting)== | ==التحقُّق من النوع والتحويلات التلقائية بين الأنواع (Casting)== | ||
يُستخدَم المعامل is للتحقق من أنّ قيمة التعبير تتبع لأحد الأنواع، وإذا ما تمّ التحقُّق من القيمة الثابتة للمتغيّرات المحليّة (immutable local variable) أو من قيمة إحدى الخاصّيات فلا حاجة للتصريح عن تحويلها (casting)، كما هو واضح بالشيفرة الآتية:<syntaxhighlight lang="kotlin"> | يُستخدَم المعامل is للتحقق من أنّ قيمة التعبير تتبع لأحد الأنواع، وإذا ما تمّ التحقُّق من القيمة الثابتة للمتغيّرات المحليّة (immutable local variable) أو من قيمة إحدى الخاصّيات فلا حاجة للتصريح عن تحويلها (casting)، كما هو واضح بالشيفرة الآتية:<syntaxhighlight lang="kotlin"> | ||
``` | ``` | ||
fun getStringLength(obj: Any): Int? { | fun getStringLength(obj: Any): Int? { | ||
if (obj is String) { | if (obj is String) { | ||
//سيُحوّل الكائن تلقائيًا في هذا الجزء إلى نوع String | //سيُحوّل الكائن تلقائيًا في هذا الجزء إلى نوع String | ||
return obj.length | return obj.length | ||
} | } | ||
//وفي هذا الجزء سيبقى من النوع Any | //وفي هذا الجزء سيبقى من النوع Any | ||
return null | return null | ||
} | } | ||
سطر 199: | سطر 153: | ||
</syntaxhighlight>أو بالشكل:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أو بالشكل:<syntaxhighlight lang="kotlin"> | ||
fun getStringLength(obj: Any): Int? { | fun getStringLength(obj: Any): Int? { | ||
if (obj !is String) return null | if (obj !is String) return null | ||
//سيُحوّل الكائن obj تلقائيًا إلى نوع String في هذا الجزء | //سيُحوّل الكائن obj تلقائيًا إلى نوع String في هذا الجزء | ||
return obj.length | return obj.length | ||
} | } | ||
</syntaxhighlight>أو بشكل آخر:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أو بشكل آخر:<syntaxhighlight lang="kotlin"> | ||
fun getStringLength(obj: Any): Int? { | fun getStringLength(obj: Any): Int? { | ||
//سيُحوّل الكائن الموجود على يمين المعامل تلقائيًا إلى نوع String | //سيُحوّل الكائن الموجود على يمين المعامل تلقائيًا إلى نوع String | ||
if (obj is String && obj.length > 0) { | if (obj is String && obj.length > 0) { | ||
return obj.length | return obj.length | ||
} | } | ||
return null | return null | ||
} | } | ||
</syntaxhighlight>المزيد عن [[الأصناف classes]] و<nowiki/>[[التحويل ما بين الأنواع type casts]]. | </syntaxhighlight>المزيد عن [[Kotlin/classes|الأصناف classes]] و<nowiki/>[[Kotlin/typecasts|التحويل ما بين الأنواع type casts]]. | ||
==استخدام حلقة For== | ==استخدام حلقة For== | ||
تُكتب حلقة for بالشكل الآتي:<syntaxhighlight lang="kotlin"> | تُكتب حلقة for بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
سطر 229: | سطر 173: | ||
for (item in items) { | for (item in items) { | ||
println(item) | println(item) | ||
} | } | ||
سطر 241: | سطر 183: | ||
for (index in items.indices) { | for (index in items.indices) { | ||
println("item at $index is ${items[index]}") | println("item at $index is ${items[index]}") | ||
} | } | ||
</syntaxhighlight>المزيد عن [[حلقة for]]. | </syntaxhighlight>المزيد عن [[Kotlin/control flow for|حلقة for]]. | ||
==استخدام حلقة While== | ==استخدام حلقة While== | ||
يكون استخدامها وفق الصيغة الآتية:<syntaxhighlight lang="kotlin"> | يكون استخدامها وفق الصيغة الآتية:<syntaxhighlight lang="kotlin"> | ||
val items = listOf("apple", "banana", "kiwi") | val items = listOf("apple", "banana", "kiwi") | ||
var index = 0 | var index = 0 | ||
while (index < items.size) { | while (index < items.size) { | ||
println("item at $index is ${items[index]}") | println("item at $index is ${items[index]}") | ||
index++ | index++ | ||
} | } | ||
سطر 265: | سطر 200: | ||
</syntaxhighlight>حيث ستستمر الحلقة لحين الوصول إلى آخر عنصر في المجموعة (بلوغ المتحول index قيمة دليل العنصر الأخير). | </syntaxhighlight>حيث ستستمر الحلقة لحين الوصول إلى آخر عنصر في المجموعة (بلوغ المتحول index قيمة دليل العنصر الأخير). | ||
المزيد عن [[حلقة while]]. | المزيد عن [[Kotlin/control flow while|حلقة while]]. | ||
==استخدام التعبير When== | ==استخدام التعبير When== | ||
يُستخدَم التعبير when للتحقق من قيمة أو إحدى خاصّيات الكائن أو المتحوِّل بالشكل الآتي:<syntaxhighlight lang="kotlin"> | يُستخدَم التعبير when للتحقق من قيمة أو إحدى خاصّيات الكائن أو المتحوِّل بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
fun describe(obj: Any): String = | fun describe(obj: Any): String = | ||
when (obj) { | when (obj) { | ||
1 -> "One" | 1 -> "One" | ||
"Hello" -> "Greeting" | "Hello" -> "Greeting" | ||
is Long -> "Long" | is Long -> "Long" | ||
!is String -> "Not a string" | !is String -> "Not a string" | ||
else -> "Unknown" | else -> "Unknown" | ||
} | } | ||
</syntaxhighlight>المزيد عن [[التعبير when]]. | </syntaxhighlight>المزيد عن [[Kotlin/control flow when|التعبير when]]. | ||
==استخدام المجالات (Ranges)== | ==استخدام المجالات (Ranges)== | ||
يُستخَدم المعامل in للتأكد من وقوع قيمةٍ ما ضمن مجالٍ مُحدَّد، وهذا يتَّضح عبر المثال الآتي:<syntaxhighlight lang="kotlin"> | يُستخَدم المعامل in للتأكد من وقوع قيمةٍ ما ضمن مجالٍ مُحدَّد، وهذا يتَّضح عبر المثال الآتي:<syntaxhighlight lang="kotlin"> | ||
val x = 10 | val x = 10 | ||
val y = 9 | val y = 9 | ||
if (x in 1..y+1) { // المجال يمتد من قيمة 1 وحتى قيمة y+1 | if (x in 1..y+1) { // المجال يمتد من قيمة 1 وحتى قيمة y+1 | ||
println("fits in range") | println("fits in range") | ||
} | } | ||
سطر 302: | سطر 227: | ||
if (-1 !in 0..list.lastIndex) { // المجال يمتد من 0 وحتى قيمة الدليل الأخير | if (-1 !in 0..list.lastIndex) { // المجال يمتد من 0 وحتى قيمة الدليل الأخير | ||
println("-1 is out of range") | println("-1 is out of range") | ||
} | } | ||
if (list.size !in list.indices) { | if (list.size !in list.indices) { | ||
println("list size is out of valid list indices range too") | println("list size is out of valid list indices range too") | ||
} | } | ||
سطر 316: | سطر 237: | ||
</syntaxhighlight>ولتكرار عددٍ من التعليمات في مجالٍ مُحدَّدٍ، تصبح الصياغة بالشكل:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>ولتكرار عددٍ من التعليمات في مجالٍ مُحدَّدٍ، تصبح الصياغة بالشكل:<syntaxhighlight lang="kotlin"> | ||
for (x in 1..5) { // المجال يمتد من 1 حتى 5 | for (x in 1..5) { // المجال يمتد من 1 حتى 5 | ||
print(x) | print(x) | ||
} | } | ||
سطر 324: | سطر 243: | ||
</syntaxhighlight>أما للتكرار المتسلسل وفق خطوة step:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أما للتكرار المتسلسل وفق خطوة step:<syntaxhighlight lang="kotlin"> | ||
for (x in 1..10 step 2) { //يبدأ المجال من القيمة 1 وينتهي بالقيمة 10 وبخطوةٍ مقدارها 2 | for (x in 1..10 step 2) { //يبدأ المجال من القيمة 1 وينتهي بالقيمة 10 وبخطوةٍ مقدارها 2 | ||
print(x) | print(x) | ||
} | } | ||
سطر 332: | سطر 249: | ||
for (x in 9 downTo 0 step 3) { // يبدأ المجال بالقيمة 9 وينتهي بشكل تنازليّ عند القيمة 0 بخطوةٍ مقدارها 3 | for (x in 9 downTo 0 step 3) { // يبدأ المجال بالقيمة 9 وينتهي بشكل تنازليّ عند القيمة 0 بخطوةٍ مقدارها 3 | ||
print(x) | print(x) | ||
} | } | ||
</syntaxhighlight>المزيد عن [[المجالات ranges]]. | </syntaxhighlight>المزيد عن [[Kotlin/ranges|المجالات ranges]]. | ||
==استخدام المجموعات (Collections)== | ==استخدام المجموعات (Collections)== | ||
يُمكن تنفيذ التكرار على العناصر الموجودة في المجموعة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | يُمكن تنفيذ التكرار على العناصر الموجودة في المجموعة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
for (item in items) { | for (item in items) { | ||
println(item) | println(item) | ||
} | } | ||
</syntaxhighlight>أما للتأكُّد من وجود عنصرٍ ما ضمن المجموعة باستخدام المعامل in تصبح الصياغة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>أما للتأكُّد من وجود عنصرٍ ما ضمن المجموعة باستخدام المعامل in تصبح الصياغة بالشكل الآتي:<syntaxhighlight lang="kotlin"> | ||
when { | when { | ||
"orange" in items -> println("juicy") | |||
"apple" in items -> println("apple is fine too") | "apple" in items -> println("apple is fine too") | ||
} | } | ||
</syntaxhighlight>كما ويمكن استخدام تعابير lambda لتصنيف وتعيين المجموعات، كما في الشيفرة الآتية:<syntaxhighlight lang="kotlin"> | </syntaxhighlight>كما ويمكن استخدام تعابير lambda لتصنيف وتعيين المجموعات، كما في الشيفرة الآتية:<syntaxhighlight lang="kotlin"> | ||
fruits | fruits | ||
.filter { it.startsWith("a") } | .filter { it.startsWith("a") } | ||
.sortedBy { it } | .sortedBy { it } | ||
.map { it.toUpperCase() } | .map { it.toUpperCase() } | ||
.forEach { println(it) } | .forEach { println(it) } | ||
</syntaxhighlight>المزيد عن [[الدوال عالية المستوى وتعابير lambdas]]. | </syntaxhighlight>المزيد عن [[Kotlin/lambdas|الدوال عالية المستوى وتعابير lambdas]]. | ||
==إنشاء الأصناف (Classes) والكائنات الناتجة عنها (Objects)== | ==إنشاء الأصناف (Classes) والكائنات الناتجة عنها (Objects)== | ||
يُوضِّح المثال الآتي إنشاء كائنَين من صنفَين مختلفين:<syntaxhighlight lang="kotlin"> | يُوضِّح المثال الآتي إنشاء كائنَين من صنفَين مختلفين:<syntaxhighlight lang="kotlin"> | ||
سطر 376: | سطر 280: | ||
</syntaxhighlight>المزيد عن [[الأصناف classes]] و<nowiki/>[[الكائنات objects]]. | </syntaxhighlight>المزيد عن [[Kotlin/classes|الأصناف classes]] و<nowiki/>[[Kotlin/object declarations|الكائنات objects]]. | ||
==مصادر== | ==مصادر== | ||
* [https://kotlinlang.org/docs/reference/basic-syntax.html صفحة البنية العامّة في توثيق لغة Kotlin] | |||
[https://kotlinlang.org/docs/reference/basic-syntax.html صفحة البنية العامّة في توثيق لغة Kotlin] |
مراجعة 05:54، 21 فبراير 2018
تعريف الحزمة (Package)
يُكتب توصيف الحزمة (package) في بداية الملف المصدريّ (source file) بالشكل الآتي:
package my.demo
import java.util.*
// ...
ولا يُشترط التوافق ما بين الحزمة (package) والمجلد الموجودة فيه (directory)، إذ من الممكن أن تتوضع الملفات المصدريّة عشوائيًّا في نظام الملفات.
المزيد عن الحزم packages.
تعريف الدالة (Function)
إن كانت الدالة بمتحولين من نوع Int وتعيد قيمةً بنوع Int أيضًا، يصبح تعريفها بالشكل:
fun sum(a: Int, b: Int): Int {
return a + b
}
أما الشيفرة الآتية فهي لتعريف دالةٍ باسم sum تحتوي على تعبير (expression) دون التصريح عن نوع القيمة المعادة:
fun sum(a: Int, b: Int) = a + b
وإن لم تُعد الدالة أية قيمةٍ بمعنىً يصبح تعريفها على النحو الآتي: (الحالة الافتراضية هي Unit)
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
ويمكن الاستغناء عن النوع المُعاد Unit ليصبح التعريف بالشكل:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
المزيد عن الدوال functions.
تعريف المتحولات (Variables)
لتعريف متحوِّلٍ محليٍّ بإسنادٍ وحيد (للقراءة فقط ولا يمكن إعطاؤه قيمةً جديدة) تُستخدَم إحدى الصيغ الآتية:
val a: Int = 1 // إسناد مباشر
val b = 2 // يُعرَّف ضمنيًّا من النوع Int
val c: Int // من الضروري تحديد النوع إن لم تُسند القيمة للمتحوّل مباشرةً
c = 3 // إسنادٌ لمتحوّل مُعرَّف مسبقًا
ولتعريف متحوِّلٍ بقيمةٍ قابلةٍ للتعديل:
var x = 5 // يُعرَّف ضمنيًا من النوع Int
x += 1
وقد تكون المتحولات واقعةً بمستوىً أعلى من البنية الحاليّة كما في المثال الآتي: (المتحولان PI و x يقعان في مستوى أعلى من الدالة incrementX)
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
المزيد عن الخاصّيات properties والحقول fields.
التعليقات (Comments)
تدعم لغة Kotlin نوعين من التعليقات (كما هو الحال في لغتَي Java و JavaScript)؛ وهما التعليقات السطريّة أو التعليقات بأكثر من سطر، وتكون صياغتهما بالشكل الآتي:
// تعليق بسطر واحد
/* هذا التعليق
بأكثر من سطر */
وعلى عكس لغة Java يُمكن للتعليقات بأكثر من سطرٍ أن تتداخل (أي أن يقع تعليقٌ داخلَ تعليقٍ آخر).
ولمعرفة المزيد من التفاصيل عن التعليقات يمكن الانتقال لصفحة توضيح آلية التوثيق للبرامج بلغة Kotlin بالانكليزية.
استخدام قوالب السلاسل النصيّة (String Templates)
تكون صياغتها بالشكل الآتي:
var a = 1
// اسم بسيط ضمن قالب نصيّ
val s1 = "a is $a"
a = 2
// تعبيرٌ عشوائيّ ضمن قالب نصيّ
val s2 = "${s1.replace("is", "was")}, but now is $a"
المزيد عن قوالب السلاسل النصية.
استخدام التعابير الشرطية (Conditional Expressions)
توضِّح الدالة الآتية (لإعادة القيمة الأكبر من بين القيمتين a و b) طريقة صياغة الشرط if:
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
وكما يمكن استخدام الشرط if بصياغة تعبيريّة بالشكل الآتي:
fun maxOf(a: Int, b: Int) = if (a > b) a else b
المزيد عن استخدام الشرط if.
استخدام القيم التي تقبل القيمة الفارغة Null والتحقُّق منها
عندما تكون القيمة null محتملة للمتحول المرجعي (reference) فيُقال عنه أنه nullable.
إن الدالة الآتية ستعيد قيمة null إن لم تحتوي السلسلة str على قيمةٍ صحيحة:
fun parseInt(str: String): Int? {
// ...
}
أما الدالة الآتية (إخراج قيمة ناتج جداء العددين الموجودين بالسلسلتين arg1 و arg2) فتعيد قيمة null:
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1) // تحويل السلسلة النصيّة إلى قيمة عددية تُخزّن في المتحول
val y = parseInt(arg2)
// قد ينتج عن عملية الجداء حدوث خطأ في حال احتواء أحد المتحولين على قيمة null
if (x != null && y != null) {
println(x * y)
}
else {
println("either '$arg1' or '$arg2' is not a number")
}
}
أو بالشكل:
// ...
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}
println(x * y)
المزيد عن القيمة الفارغة null.
التحقُّق من النوع والتحويلات التلقائية بين الأنواع (Casting)
يُستخدَم المعامل is للتحقق من أنّ قيمة التعبير تتبع لأحد الأنواع، وإذا ما تمّ التحقُّق من القيمة الثابتة للمتغيّرات المحليّة (immutable local variable) أو من قيمة إحدى الخاصّيات فلا حاجة للتصريح عن تحويلها (casting)، كما هو واضح بالشيفرة الآتية:
```
fun getStringLength(obj: Any): Int? {
if (obj is String) {
//سيُحوّل الكائن تلقائيًا في هذا الجزء إلى نوع String
return obj.length
}
//وفي هذا الجزء سيبقى من النوع Any
return null
}
أو بالشكل:
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
//سيُحوّل الكائن obj تلقائيًا إلى نوع String في هذا الجزء
return obj.length
}
أو بشكل آخر:
fun getStringLength(obj: Any): Int? {
//سيُحوّل الكائن الموجود على يمين المعامل تلقائيًا إلى نوع String
if (obj is String && obj.length > 0) {
return obj.length
}
return null
}
المزيد عن الأصناف classes والتحويل ما بين الأنواع type casts.
استخدام حلقة For
تُكتب حلقة for بالشكل الآتي:
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
إذ يُستخدَم المعامل in للمرور بكافة العناصر الموجودة في المجموعة items. ويوضح المثال الآتي استخدام حلقة for أيضًا ولكن مع الأدلة (indices) للعناصر بدلًا من العناصر نفسها:
val items = listOf("apple", "banana", "kiwi")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
المزيد عن حلقة for.
استخدام حلقة While
يكون استخدامها وفق الصيغة الآتية:
val items = listOf("apple", "banana", "kiwi")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
حيث ستستمر الحلقة لحين الوصول إلى آخر عنصر في المجموعة (بلوغ المتحول index قيمة دليل العنصر الأخير).
المزيد عن حلقة while.
استخدام التعبير When
يُستخدَم التعبير when للتحقق من قيمة أو إحدى خاصّيات الكائن أو المتحوِّل بالشكل الآتي:
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
المزيد عن التعبير when.
استخدام المجالات (Ranges)
يُستخَدم المعامل in للتأكد من وقوع قيمةٍ ما ضمن مجالٍ مُحدَّد، وهذا يتَّضح عبر المثال الآتي:
val x = 10
val y = 9
if (x in 1..y+1) { // المجال يمتد من قيمة 1 وحتى قيمة y+1
println("fits in range")
}
كما ويمكن استخدامه للتحقُّق من أنّ القيمة خارج هذا المجال، بالشكل الآتي:
val list = listOf("a", "b", "c")
if (-1 !in 0..list.lastIndex) { // المجال يمتد من 0 وحتى قيمة الدليل الأخير
println("-1 is out of range")
}
if (list.size !in list.indices) {
println("list size is out of valid list indices range too")
}
ولتكرار عددٍ من التعليمات في مجالٍ مُحدَّدٍ، تصبح الصياغة بالشكل:
for (x in 1..5) { // المجال يمتد من 1 حتى 5
print(x)
}
أما للتكرار المتسلسل وفق خطوة step:
for (x in 1..10 step 2) { //يبدأ المجال من القيمة 1 وينتهي بالقيمة 10 وبخطوةٍ مقدارها 2
print(x)
}
println()
for (x in 9 downTo 0 step 3) { // يبدأ المجال بالقيمة 9 وينتهي بشكل تنازليّ عند القيمة 0 بخطوةٍ مقدارها 3
print(x)
}
المزيد عن المجالات ranges.
استخدام المجموعات (Collections)
يُمكن تنفيذ التكرار على العناصر الموجودة في المجموعة بالشكل الآتي:
for (item in items) {
println(item)
}
أما للتأكُّد من وجود عنصرٍ ما ضمن المجموعة باستخدام المعامل in تصبح الصياغة بالشكل الآتي:
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
كما ويمكن استخدام تعابير lambda لتصنيف وتعيين المجموعات، كما في الشيفرة الآتية:
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }
المزيد عن الدوال عالية المستوى وتعابير lambdas.
إنشاء الأصناف (Classes) والكائنات الناتجة عنها (Objects)
يُوضِّح المثال الآتي إنشاء كائنَين من صنفَين مختلفين:
val rectangle = Rectangle(5.0, 2.0) // لا حاجة لكلمة new
val triangle = Triangle(3.0, 4.0, 5.0)
المزيد عن الأصناف classes والكائنات objects.