کاتلین فارسی

فهرست

الف ) درباره این کتاب

ب ) آیا این کتاب مناسب شماست؟

پ ) درباره نویسنده

ت ) چند سخن مترجم

1 - معرفی

1.1 )‌ کاتلین چیست؟

1.2 ) با کاتلین به چه میرسیم؟

2 - آماده شدن

2.1 ) اندروید استودیو

2.2 ) نصب پلاگین کاتلین

3 - ساختن یک پروژه جدید

3.1 ) ساختن پروژه در اندروید استودیو

3.2 ) تنظیمات گردل

3.3 ) تبدیل MainActivity به کد کاتلین

3.4 ) تست کارکردن همه اجزا

4 - کلاس ها و توابع

4.1 ) روش تعریف کلاس

4.2 ) ارث بری

4.3 ) توابع

4.4 ) کانستراکتور و پارامترها

5 - نوشتن اولین کلاس

5.1 ) ساختن layout

5.2 ) آداپتور Recycler

6 - مقادیر و خصیصه ها

6.1 ) type های پایه ای

6.2 ) متغیر ها

6.3 ) خصیصه ها

7 - Anko و توابع الحاقی

7.1 ) Anko چیست؟

7.2 ) شروع به استفاده از Anko

7.3 ) توابع الحاقی

8 - بدست آوردن دیتا با استفاده از API

8.1 ) انجام درخواست

8.2 ) انجام درخواست خارج از نخ اصلی

9 - کلاس های دیتا

9.1 ) توابع اضافی

9.2 ) کپی کردن کلاس دیتا

9.3 ) مپ کردن یک آبجکت به متغیرها

10 - تجزیه دیتا

10.1 ) تبدیل JSON به کلاس های دیتا

10.2 ) شکل دادن به لایه ی domain

10.3 ) نمایش دیتا بر روی UI

11 - Overloading Operators

11.1 ) جدول اوپراتور ها

11.2 ) یک مثال

11.3 ) عملگرها در توابع الحاقی

12 - تجزیه دیتا

بقیه فصل ها در حال ترجمه است

Overloading Operators

ویرایش

کاتلین تعداد مشخصی از آوپراتور های نمادین دارد که میتونیم به راحتی بر روی هر کلاسی استفاده کنیم. روشش هم ایجاد یک تابع با نام رزرو شده و مپ کردن اون به سمبله. Overload کردن این اوپراتور ها ساده نویسی و خانایی کد رو بیشتر کنه.

اگر بخوایم کامپایلر رو آگاه کنیم که یک اوپراتور رو میخوایم overload کنیم، باید اون تابع رو با اصلاح کننده operator مشخص کنیم.

جدول اوپراتور ها

در جدول زیر هم میتونید یک سری از جدول ها رو ببینید که شامل اوپراتورها و دستور العمل های مطابق آن است. یک تابع که پیاده سازی شده باشد برای استفاده از آن اوپراتور در کلاس مشخص نیاز است.

Unary Operations

   
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()
a-- a.dec()

Binary Operations

   
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(b)
a..b a.rangTo(b)
a in b b.contains(a)
a !in b !b.contains(a)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)

Array-like operations

   
a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1,..., i_n] a.get(i_1,..., i_n)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1,..., i_n] = b a.set(i_1, …, i_n, b)

Equals operation

   
a == b a?.equals(b) ?: b === null
a != b !(a?.equals(b) ?: b === null)

عملگرهای equals مقداری متفاوتند، زیرا برای بهتر چک کردن تساوی از ترجمه ی پیچیده تری استفاده میکند که در نتیجه تابع باید دقیقا به صورت زیر پیاده سازی شود.

operator fun equals(other: Any?): Boolean

Function invocation

   
a(i) a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, …, i_n) a.invoke(i_1,..., i_n)

یک مثال

همانطور که تصور میکنید لیست های کاتلینی عملگرهای array-like ای به مانند بالا که گفته شده را دارا میباشد که در نتیجه به مانند جاوا میتونیم به آیتم های یک لیست دسترسی داشته باشیم ولی این تنها به این محدود نمیشود و در لیست های mutable (تغییرپذیر)، هر آیتم میتونه به صورت مستقیم مقدار دهی بشه.

val x = myList[2]
myList[2] = 4

اگر به یاد داشته باشید، کلاس دیتایی به نام ForecastList داشتیم که تشکیل شده از یک لیست با مقداری اطلاعات اضافی بود. اگه به جای این که درخواستی به لیست های داخلی برای بدست آوردن یک آیتم از اون بکنیم، به آیتم ها مستقیما دسترسی داشته باشیم، جالب تر خواهد بود. در ضمن، یک تابع به نام size() رو هم پیاده سازی میکنیم که آداپتور فعلی را ساده تر خواهد کرد.

data class ForecastList(val city: String, val country: String,
                        val dailyForecast: List<Forecast>) {
    operator fun get(position: Int): Forecast = dailyForecast[position]
    fun size(): Int = dailyForecast.size
}

که این onBindViewHolder امون رو رو مقداری ساده تر خواهد کرد.

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    with(weekForecast[position]) {
        holder.textView.text = "$date - $description - $high/$low"
    }
}

همچنین getItemCount() نیز:

override fun getItemCount(): Int = weekForecast.size()

عملگرها در توابع الحاقی

لازم نیست که به کلاس های خودمون بسنده کنیم و میتونیم کلاس هامون رو با استفاده از توابع الحاقی گسترش بدیم. به عنوان مثال میتونیم مثل روش دستیابی به لیست ها، به ViewGroup هامون هم دستیابی داشته باشیم:

operator fun ViewGroup.get(position: Int): View
        = getChildAt(position)

حالا میتونیم خیلی ساده View مورد نظر رو از ViewGroup با استفاده از position به دست بیاریم.

val container: ViewGroup = find(R.id.container)
val view = container[2]