كوتلن (Kotlin) هي لغة برمجة مخصّصة لمنصّة جافا الافتراضية (Java Virtual Machine أو اختصارًا JVM)، الأندرويد، والمتّصفح. تنتمي للغات statically typed (التي تفحص الأنواع وقت الترجمة). وهي متوافقة مع جافا 100%.
// (//)التعليقات على سطر واحد تبدأ بـ/* التعليقات المؤلفة من عدة أسطر تبدو كهذه */
تعمل الكلمة المفتاحية package
بنفس طريقة جافا
package com.learnxinyminutes.kotlin
نقطة الإدخال لبرامج Kotlin هي دالة(تابع) تسمى main
،يمرر التّابع مصفوفة تحتوي على وسطاء arguments لسطر الأوامر.
fun main(args: Array<String>) {
التّصريح عن القيم يتم باستخدام إما var
أو val
،تصريح val
لا يمكن إعادة تعيينه، في حين يمكن ذلك في var
val fooVal =10
لا يمكننا لاحقًا إعادة تعيين قيمة fooVal
لقيمة أخرى.
var fooVar =10
fooVar =20
من الممكن إعادة تعيين قيمة fooVar
. في أغلب الحالات، يمكن لكوتلن أن تحدّد ما هو نوع المتغير، لذلك لا داعي لتحديده صراحة في كل مرّة. يمكننا أن نصرّح بنوع المتغير بوضوح كالتالي:
val foo:Int=7
يمكن تمثيل السلاسل بطريقة مماثلة في java. يتم الهروب باستخدام backslash.
val fooString ="My String Is Here!"
val barString ="Printing on a new line?\nNo Problem!"
val bazString ="Do you want to add a tab?\tNo Problem!"
println(fooString)
println(barString)
println(bazString)
تُحدد السلسلة الخام string raw باستخدام triple quote ("""
). ويمكن أن تحتوي أسطر جديدة و أية محارف أخرى.
val fooRawString ="""
fun helloWorld(val name :String){
println("Hello, world!")}"""
println(fooRawString)
السلاسل ممكن أن تحتوي تعابير القالب template expressions. تبدأ تعابير القالب بالرمز $
.
val fooTemplateString ="$fooString has ${fooString.length} characters"
println(fooTemplateString)// => My String Is Here! has 18 characters
من أجل المتغيرات التي تحوي قيمة فارغة null
يجب تحديد ذلك صراحة nullable
. يمكن تحديد المتغير قابلاً للقيمة null
بإلحاق?
بنوعه. ويمكننا الوصول إلى المتحولات القابلة لـ null
باستخدام مُعامل التشغيل?
،ويمكننا استخدام عامل التشغيل :?
لتحديد قيمة بديلة للاستخدام إذا كان المتغير فارغ null
.
var fooNullable:String?="abc"
println(fooNullable?.length)// => 3
println(fooNullable?.length ?:-1)// => 3
fooNullable = null
println(fooNullable?.length)// => null
println(fooNullable?.length ?:-1)// => -1
يمكن التصريح عن الدوال باستخدام الكلمة المفتاحية fun
. وتحدد وسطاء الدالة بين قوسين بعد اسم الدالة. ويمكن لوسطاء الدالة اختياريًا الاحتواء على قيمة افتراضية. ويحدّد نوع إرجاع الدالة، إذا لزم الامر بعد المعطيات.
fun hello(name:String="world"):String{return"Hello, $name!"}
println(hello("foo"))// => Hello, foo!
println(hello(name ="bar"))// => Hello, bar!
println(hello())// => Hello, world!
يمكن لبارامتر الدالة أن يوسم بالكلمة المفتاحية vararg
للسماح بتمرير عدد متغير من المعطيات إلى الدالة.
fun varargExample(vararg names:Int){
println("Argument has ${names.size} elements")}
varargExample()// => لا يحوي الوسيط أية عناصر
varargExample(1)// => يحوي الوسيط عنصر واحد
varargExample(1,2,3)// => يحوي الوسيط 3 عناصر
عندما تتكوّن الدّالة من تعبير واحد فقط، يمكن حذف الأقواس المنحنية { }
ويتم تحديد الجسم(العملية) بعد رمز =
fun odd(x:Int):Boolean= x %2==1
println(odd(6))// => false
println(odd(7))// => true
إذا كان نوع الاسترجاع يمكن استنتاجه فلسنا بحاجة لتحديده.
fun even(x:Int)= x %2==0
println(even(6))// => true
println(even(7))// => false
الدوال يمكن أن تأخذ دوال كوسطاء وترجع دالة.
fun not(f:(Int)->Boolean):(Int)->Boolean{return{n ->!f.invoke(n)}}
يمكن للدوال المسمّاة أن تحدّد كوسائط باستخدام معامل التشغيل
val notOdd = not(::odd)
val notEven = not(::even)
يمكن تحديد تعابير Lambda كوسائط
val notZero = not {n -> n ==0}
إذا احتوت lambda على بارامتر واحد فقط يمكن حذف التصريح عنه (جنبًا إلى جنب مع<-
)وسيكون اسم البارامتر الوحيد it
.
val notPositive = not {it >0}for(i in 0..4){
println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")}
تستخدم الكلمة المفتاحية class
للتّصريح عن الأصناف.
class ExampleClass(val x:Int){ fun memberFunction(y:Int):Int{return x + y } infix fun infixMemberFunction(y:Int):Int{return x * y }}
لإنشاء حالة instance جديدة نستدعي الباني. ولاحظ أن Kotlin لا تحوي الكلمة المفتاحية new
.
val fooExampleClass =ExampleClass(7)
يمكن استدعاء دوال المستخدم باستخدام التنويت النقطي .
println(fooExampleClass.memberFunction(4))// => 11
إذا وُسمت الدالة بالكلمة المفتاحية infix
يمكن عندها أن يستدعى باستخدام التنويت الداخلي
println(fooExampleClass infixMemberFunction 4)// => 28
أصناف البيانات Data classes هي طريقة مختصرة لإنشاء الأصناف التي تحتوي بيانات فقط وتنشئ دوال hashCode
،equals
و toString
تلقائيًا.
data classDataClassExample(val x:Int, val y:Int, val z:Int)
val fooData =DataClassExample(1,2,4)
println(fooData)// => DataClassExample(x=1, y=2, z=4)
أصناف البيانات لديها دالة copy
val fooCopy = fooData.copy(y =100)
println(fooCopy)// => DataClassExample(x=1, y=100, z=4)
يمكن أن تفكَك الكائنات Objects في متغيرات متعددة
val (a, b, c)= fooCopy
println("$a $b $c")// => 1 100 4
التفكيك باستخدام حلقة for
for((a, b, c) in listOf(fooData)){
println("$a $b $c")// => 1 100 4}
val mapData = mapOf("a" to 1,"b" to 2)
Map.Entry قابل للتفكيك كذلك
for((key, value) in mapData){
println("$key -> $value")}
الدالة with
مشابهة لعبارة with
في جافا
data classMutableDataClassExample(var x:Int, var y:Int, var z:Int)
val fooMutableData =MutableDataClassExample(7,4,9)
with (fooMutableData){
x -=2
y +=2
z--}
println(fooMutableData)// => MutableDataClassExample(x=5, y=6, z=8)
يمكننا إنشاء قائمة (لائحة) باستخدام الدالة listOf
. ستكون القائمة غير قابلة للتغيير ولا يمكن إضافة عناصر أو إزالتها.
val fooList = listOf("a","b","c")
println(fooList.size)// => 3
println(fooList.first())// => a
println(fooList.last())// => c// index يمكن الوصول إلى عناصر القائمة من خلال فهرسها
println(fooList[1])// => b
يمكن إنشاء قائمة قابلة للتعديل باستخدام الدالة mutableListOf
val fooMutableList = mutableListOf("a","b","c")
fooMutableList.add("d")
println(fooMutableList.last())// => d
println(fooMutableList.size)// => 4
يمكن إنشاء تعيين set باستخدام الدّالة setOf
val fooSet = setOf("a","b","c")
println(fooSet.contains("a"))// => true
println(fooSet.contains("z"))// => false
يمكننا إنشاء خريطة map باستخدام الدّالة mapOf
val fooMap = mapOf("a" to 8,"b" to 7,"c" to 9)
يمكن الوصول لقيم الـ Map من خلال مفاتيحها
println(fooMap["a"])// => 8
تُمثل المتتالية Sequences مجموعات تقييمها مؤجل إلى حين الحاجة lazily-evaluated collections. ويمكننا إنشاء متتالية باستخدام الدّالة generateSequence
.
val fooSequence = generateSequence(1,{ it +1})
val x = fooSequence.take(10).toList()
println(x)// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
مثال لاستخدام متتالية لتوليد أرقام فيبانوتشي fibonacci
fun fibonacciSequence():Sequence<Long>{
var a =0L
var b =1L
fun next():Long{
val result = a + b
a = b
b = result
return a
}return generateSequence(::next)}
val y = fibonacciSequence().take(10).toList()
println(y)// => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
تزوّد Kotlin دوال عالية الرتبة للعمل مع المجموعات collections
val z =(1..9).map{it *3}.filter {it <20}.groupBy {it %2==0}.mapKeys {if(it.key)"even"else"odd"}
println(z)// => {odd=[3, 9, 15], even=[6, 12, 18]}
يمكن استخدام حلقة for
مع أي شيء يؤمن التكرار.
for(c in "hello"){
println(c)}
تعمل حلقات while
بشكل مشابه لعملها في اللغات الأخرى
var ctr =0while(ctr <5){
println(ctr)
ctr++}do{
println(ctr)
ctr++}while(ctr <10)
يمكن استخدام if
كتعبير يرجع القيم. لهذا السبب ليس هناك حاجة لمعامل التشغيل :?
في Kotlin.
val num =5
val message =if(num %2==0)"even"else"odd"
println("$num is $message")// => 5 is odd
يمكن استخدام when
كبديل لسلاسل if-else if
val i =10
when {
i <7-> println("first block")
fooString.startsWith("hello")-> println("second block")else-> println("else block")}
يمكن استخدام when
مع المعطيات.
when (i){0,21-> println("0 or 21")
in 1..20-> println("in the range 1 to 20")else-> println("none of the above")}
يمكن استخدام when
كدالة ترجع القيم.
var result = when (i){0,21->"0 or 21"
in 1..20->"in the range 1 to 20"else->"none of the above"}
println(result)
يمكننا التحقق فيما إذا كان الكائن object من نوع محدّد باستخدام معامل التشغيل is
. إذا مرر الكائن فحص النوع type check عندها يمكن استخدام هذا النوع دون الموائمة بشكل صريح.
fun smartCastExample(x:Any):Boolean{if(x is Boolean){
X توائم أوتوماتيكيًا إلى Boolean
return x
}elseif(x is Int){
X توائم أوتوماتيكيًا إلى Int
return x >0}elseif(x is String){
X توائم أوتوماتيكيًا إلى String
return x.isNotEmpty()}else{returnfalse}}
println(smartCastExample("Hello, world!"))// => true
println(smartCastExample(""))// => false
println(smartCastExample(5))// => true
println(smartCastExample(0))// => false
println(smartCastExample(true))// => true
تعمل الموائمة الذكيّة smartcast
أيضًا مع كتلة when
fun smartCastWhenExample(x:Any)= when (x){
is Boolean-> x
is Int-> x >0
is String-> x.isNotEmpty()else->false}
الملحقات Extensions هي طريقة لإضافة وظائف جديدة للصنف class
. وهي مشابهة لدوال ملحقات #C
fun String.remove(c:Char):String{returnthis.filter {it != c}}
println("Hello, world!".remove('l'))// => Hello, word!
println(EnumExample.A)// => A
println(ObjectExample.hello())// => hello
أصناف Enum مشابهة لأنواع enum
في جافا.
enumclassEnumExample{
A, B, C
}
يمكن استخدام الكلمة المفتاحية object
لإنشاء كائنات وحيدة. لا يمكننا تمثيلها ولكن يمكن أن نشير لحالتها الفريدة من خلال اسمها. وهذا مشابه لكائنات Scala singleton
object ObjectExample{
fun hello():String{return"hello"}}
fun useObject(){ObjectExample.hello()
val someRef:Any=ObjectExample//كماهي تمامًا objects نستخدم أسماء الكائنات }
ترجمة -وبتصرّف- للمقال Learn kotlin in Y Minutes
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.