প্রোগ্রামারদের জন্য কোটলিন বুটক্যাম্প 6: কার্যকরী ম্যানিপুলেশন

এই কোডল্যাবটি প্রোগ্রামারদের কোর্সের জন্য কোটলিন বুটক্যাম্পের অংশ। আপনি যদি ক্রমানুসারে কোডল্যাবগুলির মাধ্যমে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন৷ আপনার জ্ঞানের উপর নির্ভর করে, আপনি কিছু বিভাগ স্কিম করতে সক্ষম হতে পারেন। এই কোর্সটি এমন প্রোগ্রামারদের জন্য তৈরি যারা একটি অবজেক্ট-ওরিয়েন্টেড ভাষা জানেন এবং কোটলিন শিখতে চান।

ভূমিকা

এটি কোটলিন বুটক্যাম্পের চূড়ান্ত কোডল্যাব। এই কোডল্যাবে আপনি টীকা এবং লেবেলযুক্ত বিরতি সম্পর্কে শিখবেন। আপনি ল্যাম্বডাস এবং উচ্চ-ক্রম ফাংশন পর্যালোচনা করেন, যা কোটলিনের মূল অংশ। এছাড়াও আপনি ইনলাইনিং ফাংশন এবং একক বিমূর্ত পদ্ধতি (SAM) ইন্টারফেস সম্পর্কে আরও জানুন। অবশেষে, আপনি কোটলিন স্ট্যান্ডার্ড লাইব্রেরি সম্পর্কে আরও জানুন।

একটি একক নমুনা অ্যাপ তৈরি করার পরিবর্তে, এই কোর্সের পাঠগুলি আপনার জ্ঞান তৈরি করার জন্য ডিজাইন করা হয়েছে, তবে একে অপরের থেকে আধা-স্বতন্ত্র থাকুন যাতে আপনি আপনার পরিচিত বিভাগগুলিকে স্কিম করতে পারেন। তাদের একসাথে বাঁধতে, অনেক উদাহরণ একটি অ্যাকোয়ারিয়াম থিম ব্যবহার করে। এবং আপনি যদি সম্পূর্ণ অ্যাকোয়ারিয়ামের গল্প দেখতে চান, তাহলে প্রোগ্রামারদের জন্য কোটলিন বুটক্যাম্প উদাসিটি কোর্সটি দেখুন।

আপনি ইতিমধ্যে কি জানা উচিত

  • কোটলিন ফাংশন, ক্লাস এবং পদ্ধতির সিনট্যাক্স
  • কিভাবে IntelliJ IDEA এ একটি নতুন ক্লাস তৈরি করবেন এবং একটি প্রোগ্রাম চালাবেন
  • ল্যাম্বডাস এবং উচ্চ-ক্রম ফাংশনের মূল বিষয়গুলি৷

আপনি কি শিখবেন

  • টীকা মৌলিক
  • লেবেলযুক্ত বিরতিগুলি কীভাবে ব্যবহার করবেন
  • উচ্চ ক্রম ফাংশন সম্পর্কে আরো
  • একক বিমূর্ত পদ্ধতি (SAM) ইন্টারফেস সম্পর্কে
  • কোটলিন স্ট্যান্ডার্ড লাইব্রেরি সম্পর্কে

আপনি কি করবেন

  • একটি সহজ টীকা তৈরি করুন।
  • একটি লেবেল বিরতি ব্যবহার করুন.
  • কোটলিনে ল্যাম্বডা ফাংশন পর্যালোচনা করুন।
  • উচ্চ-ক্রম ফাংশন ব্যবহার করুন এবং তৈরি করুন।
  • কিছু একক বিমূর্ত পদ্ধতি ইন্টারফেস কল.
  • কোটলিন স্ট্যান্ডার্ড লাইব্রেরি থেকে কিছু ফাংশন ব্যবহার করুন।

টীকাগুলি কোডে মেটাডেটা সংযুক্ত করার একটি উপায় এবং এটি কোটলিনের জন্য নির্দিষ্ট কিছু নয়। টীকাগুলি কম্পাইলার দ্বারা পড়া হয় এবং কোড বা লজিক তৈরি করতে ব্যবহৃত হয়। অনেক ফ্রেমওয়ার্ক, যেমন Ktor এবং Kotlinx , সেইসাথে Room , কীভাবে তারা চলে এবং আপনার কোডের সাথে ইন্টারঅ্যাক্ট করে তা কনফিগার করতে টীকা ব্যবহার করে। আপনি ফ্রেমওয়ার্ক ব্যবহার করা শুরু না করা পর্যন্ত কোনো টীকাটির সম্মুখীন হওয়ার সম্ভাবনা নেই, তবে কীভাবে একটি টীকা পড়তে হয় তা জানার জন্য এটি কার্যকর।

কোটলিন স্ট্যান্ডার্ড লাইব্রেরির মাধ্যমে পাওয়া যায় এমন টীকাও রয়েছে যা কোড কম্পাইল করার পদ্ধতি নিয়ন্ত্রণ করে। আপনি যদি জাভা কোডে কোটলিন রপ্তানি করেন তবে এগুলি সত্যিই দরকারী, তবে অন্যথায় আপনার প্রায়শই সেগুলির প্রয়োজন হয় না।

টীকাগুলি টীকা করা জিনিসের ঠিক আগে চলে যায় এবং বেশিরভাগ জিনিসই টীকা করা যেতে পারে—ক্লাস, ফাংশন, পদ্ধতি এবং এমনকি নিয়ন্ত্রণ কাঠামো। কিছু টীকা আর্গুমেন্ট নিতে পারে.

এখানে কিছু টীকা একটি উদাহরণ.

@file:JvmName("InteropFish")
class InteropFish {
   companion object {
       @JvmStatic fun interop()
   }
}

এটি বলে যে এই ফাইলটির রপ্তানি করা নামটি JvmName টীকা সহ InteropFish ; JvmName টীকাটি "InteropFish" এর একটি যুক্তি গ্রহণ করছে। সহচর বস্তুতে, @JvmStatic কোটলিনকে interop() InteropFish এ একটি স্ট্যাটিক ফাংশন তৈরি করতে বলে।

আপনি আপনার নিজস্ব টীকাও তৈরি করতে পারেন, তবে এটি বেশিরভাগই উপযোগী যদি আপনি এমন একটি লাইব্রেরি লিখছেন যা রানটাইমে ক্লাস সম্পর্কে বিশেষ তথ্যের প্রয়োজন হয়, সেটি হল প্রতিফলন

ধাপ 1: একটি নতুন প্যাকেজ এবং ফাইল তৈরি করুন

  1. src এর অধীনে, একটি নতুন প্যাকেজ তৈরি করুন, example
  2. উদাহরণস্বরূপ , একটি নতুন Kotlin ফাইল তৈরি করুন, Annotations.kt

ধাপ 2: আপনার নিজস্ব টীকা তৈরি করুন

  1. Annotations.kt এ, দুটি পদ্ধতি, trim() এবং fertilize() সহ একটি Plant ক্লাস তৈরি করুন।
class Plant {
        fun trim(){}
        fun fertilize(){}
}
  1. একটি ফাংশন তৈরি করুন যা একটি ক্লাসের সমস্ত পদ্ধতি প্রিন্ট করে। রানটাইমে একটি ক্লাস সম্পর্কে তথ্য পেতে ::class ব্যবহার করুন। একটি ক্লাসের পদ্ধতির একটি তালিকা পেতে declaredMemberFunctions ব্যবহার করুন। (এটি অ্যাক্সেস করতে, আপনাকে kotlin.reflect.full.* আমদানি করতে হবে)
import kotlin.reflect.full.*    // required import

class Plant {
    fun trim(){}
    fun fertilize(){}
}

fun testAnnotations() {
    val classObj = Plant::class
    for (m in classObj.declaredMemberFunctions) {
        println(m.name)
    }
}
  1. আপনার পরীক্ষার রুটিন কল করার জন্য একটি main() ফাংশন তৈরি করুন। আপনার প্রোগ্রাম চালান এবং আউটপুট পর্যবেক্ষণ.
fun main() {
    testAnnotations()
}
⇒ trim
fertilize
  1. একটি সহজ টীকা তৈরি করুন, ImAPlant
annotation class ImAPlant

এটি টীকা বলা ছাড়া অন্য কিছু করে না।

  1. আপনার Plant ক্লাসের সামনে টীকা যোগ করুন।
@ImAPlant class Plant{
    ...
}
  1. একটি ক্লাসের সমস্ত টীকা প্রিন্ট করতে testAnnotations() পরিবর্তন করুন। একটি ক্লাসের সমস্ত টীকা পেতে annotations ব্যবহার করুন। আপনার প্রোগ্রাম চালান এবং ফলাফল পর্যবেক্ষণ.
fun testAnnotations() {
    val plantObject = Plant::class
    for (a in plantObject.annotations) {
        println(a.annotationClass.simpleName)
    }
}
⇒ ImAPlant
  1. ImAPlant টীকা খুঁজতে testAnnotations() পরিবর্তন করুন। একটি নির্দিষ্ট টীকা খুঁজতে findAnnotation() ব্যবহার করুন। আপনার প্রোগ্রাম চালান এবং ফলাফল পর্যবেক্ষণ.
fun testAnnotations() {
    val plantObject = Plant::class
    val myAnnotationObject = plantObject.findAnnotation<ImAPlant>()
    println(myAnnotationObject)
}
⇒ @example.ImAPlant()

ধাপ 3: একটি লক্ষ্যযুক্ত টীকা তৈরি করুন

টীকা গেটার বা সেটারদের টার্গেট করতে পারে। যখন তারা করে, আপনি তাদের @get: বা @set: উপসর্গ দিয়ে প্রয়োগ করতে পারেন। টীকা সহ ফ্রেমওয়ার্ক ব্যবহার করার সময় এটি অনেক বেশি আসে।

  1. দুটি টীকা ঘোষণা করুন, OnGet যা শুধুমাত্র প্রপার্টি প্রাপ্তদের জন্য প্রয়োগ করা যেতে পারে এবং OnSet যা শুধুমাত্র প্রপার্টি সেটারের ক্ষেত্রে প্রয়োগ করা যেতে পারে। প্রতিটিতে @Target(AnnotationTarger.PROPERTY_GETTER) বা PROPERTY_SETTER ব্যবহার করুন।
annotation class ImAPlant

@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class OnGet
@Target(AnnotationTarget.PROPERTY_SETTER)
annotation class OnSet

@ImAPlant class Plant {
    @get:OnGet
    val isGrowing: Boolean = true

    @set:OnSet
    var needsFood: Boolean = false
}

লাইব্রেরি তৈরির জন্য টীকাগুলি সত্যিই শক্তিশালী যা রানটাইমে এবং কখনও কখনও কম্পাইলের সময় উভয় জিনিসগুলি পরিদর্শন করে। যাইহোক, সাধারণ অ্যাপ্লিকেশন কোড শুধুমাত্র ফ্রেমওয়ার্ক দ্বারা প্রদত্ত টীকা ব্যবহার করে।

কোটলিনের প্রবাহ নিয়ন্ত্রণের বিভিন্ন উপায় রয়েছে। আপনি ইতিমধ্যেই return এর সাথে পরিচিত, যা একটি ফাংশন থেকে এর এনক্লোসিং ফাংশনে ফিরে আসে। break ব্যবহার করা return মত, কিন্তু লুপের জন্য।

কোটলিন আপনাকে লুপগুলির উপর অতিরিক্ত নিয়ন্ত্রণ দেয় যাকে লেবেলযুক্ত বিরতি বলা হয়। একটি লেবেল সহ যোগ্য একটি break সেই লেবেল দিয়ে চিহ্নিত লুপের ঠিক পরেই এক্সিকিউশন পয়েন্টে চলে যায়। নেস্টেড লুপগুলির সাথে ডিল করার সময় এটি বিশেষভাবে কার্যকর।

কোটলিনের যেকোনো অভিব্যক্তি একটি লেবেল দিয়ে চিহ্নিত করা যেতে পারে। লেবেলগুলির একটি শনাক্তকারীর ফর্ম রয়েছে যার পরে @ চিহ্ন রয়েছে৷

  1. Annotations.kt এ, একটি অভ্যন্তরীণ লুপ থেকে ব্রেক আউট করে একটি লেবেলযুক্ত বিরতি চেষ্টা করুন৷
fun labels() {
    outerLoop@ for (i in 1..100) {
         print("$i ")
         for (j in 1..100) {
             if (i > 10) break@outerLoop  // breaks to outer loop
        }
    }
}

fun main() {
    labels()
}
  1. আপনার প্রোগ্রাম চালান এবং আউটপুট পর্যবেক্ষণ.
⇒ 1 2 3 4 5 6 7 8 9 10 11 

একইভাবে, আপনি একটি লেবেলযুক্ত continue ব্যবহার করতে পারেন। লেবেলযুক্ত লুপটি ভেঙে ফেলার পরিবর্তে, লেবেলযুক্ত অবিরত লুপের পরবর্তী পুনরাবৃত্তিতে এগিয়ে যায়।

ল্যাম্বডাস হল বেনামী ফাংশন, যেগুলো কোনো নাম ছাড়াই ফাংশন। আপনি তাদের ভেরিয়েবলে বরাদ্দ করতে পারেন এবং ফাংশন এবং পদ্ধতিতে আর্গুমেন্ট হিসাবে তাদের পাস করতে পারেন। তারা অত্যন্ত দরকারী.

ধাপ 1: একটি সাধারণ ল্যাম্বডা তৈরি করুন

  1. IntelliJ IDEA, Tools > Kotlin > Kotlin REPL- এ REPL শুরু করুন।
  2. একটি যুক্তি দিয়ে একটি ল্যাম্বডা তৈরি করুন, dirty: Int যা একটি গণনা করে, dirty 2 দ্বারা ভাগ করে। ল্যাম্বডাকে একটি পরিবর্তনশীল, waterFilter বরাদ্দ করুন।
val waterFilter = { dirty: Int -> dirty / 2 }
  1. waterFilter কল করুন, 30 এর মান পাস করে।
waterFilter(30)
⇒ res0: kotlin.Int = 15

ধাপ 2: একটি ফিল্টার ল্যাম্বডা তৈরি করুন

  1. এখনও REPL-এ, একটি বৈশিষ্ট্য, name সহ একটি ডেটা ক্লাস, Fish তৈরি করুন।
data class Fish(val name: String)
  1. Flipper, Moby Dick, এবং Dory নামের ৩টি Fish একটি তালিকা তৈরি করুন।
val myFish = listOf(Fish("Flipper"), Fish("Moby Dick"), Fish("Dory"))
  1. 'i' অক্ষর রয়েছে এমন নামগুলি পরীক্ষা করতে একটি ফিল্টার যোগ করুন।
myFish.filter { it.name.contains("i")}
⇒ res3: kotlin.collections.List<Line_1.Fish> = [Fish(name=Flipper), Fish(name=Moby Dick)]

ল্যাম্বডা এক্সপ্রেশনে, it বর্তমান তালিকা উপাদানকে বোঝায়, এবং ফিল্টারটি প্রতিটি তালিকা উপাদানে পালাক্রমে প্রয়োগ করা হয়।

  1. বিভাজক হিসাবে ", " ব্যবহার করে ফলাফলে joinString() প্রয়োগ করুন।
myFish.filter { it.name.contains("i")}.joinToString(", ") { it.name }
⇒ res4: kotlin.String = Flipper, Moby Dick

joinToString() ফাংশনটি নির্দিষ্ট স্ট্রিং দ্বারা আলাদা করে ফিল্টার করা নামগুলির সাথে যোগ দিয়ে একটি স্ট্রিং তৈরি করে। এটি কোটলিন স্ট্যান্ডার্ড লাইব্রেরিতে নির্মিত অনেক দরকারী ফাংশনের মধ্যে একটি।

একটি ফাংশনের যুক্তি হিসাবে একটি ল্যাম্বডা বা অন্য ফাংশন পাস করা একটি উচ্চ-ক্রম ফাংশন তৈরি করে। উপরের ফিল্টারটি এর একটি সহজ উদাহরণ। filter() একটি ফাংশন, এবং আপনি এটিকে একটি ল্যাম্বডা পাস করেন যা তালিকার প্রতিটি উপাদান কীভাবে প্রক্রিয়া করতে হয় তা নির্দিষ্ট করে।

এক্সটেনশন ল্যাম্বডাস সহ উচ্চ-ক্রম ফাংশন লেখা কোটলিন ভাষার সবচেয়ে উন্নত অংশগুলির মধ্যে একটি। এগুলি কীভাবে লিখতে হয় তা শিখতে কিছুটা সময় লাগে তবে এগুলি ব্যবহার করা সত্যিই সুবিধাজনক৷

ধাপ 1: একটি নতুন ক্লাস তৈরি করুন

  1. উদাহরণ প্যাকেজের মধ্যে, একটি নতুন Kotlin ফাইল তৈরি করুন, Fish.kt
  2. Fish.kt এ, একটি বৈশিষ্ট্য, name সহ একটি ডেটা ক্লাস Fish তৈরি করুন।
data class Fish (var name: String)
  1. একটি ফাংশন তৈরি করুন fishExamples()fishExamples() এ, "splashy" নামে একটি মাছ তৈরি করুন, সব ছোট হাতের।
fun fishExamples() {
    val fish = Fish("splashy")  // all lowercase
}
  1. একটি main() ফাংশন তৈরি করুন যা কল করে fishExamples()
fun main () {
    fishExamples()
}
  1. main() এর বাম দিকে সবুজ ত্রিভুজটিতে ক্লিক করে আপনার প্রোগ্রামটি কম্পাইল করুন এবং চালান। এখনও কোন আউটপুট নেই.

ধাপ 2: একটি উচ্চ-অর্ডার ফাংশন ব্যবহার করুন

with() ফাংশন আপনাকে আরও কমপ্যাক্ট উপায়ে একটি বস্তু বা সম্পত্তির এক বা একাধিক রেফারেন্স করতে দেয়। this ব্যবহার করে। with() আসলে একটি উচ্চ-অর্ডার ফাংশন, এবং লাম্বাতে আপনি সরবরাহ করা বস্তুর সাথে কী করতে হবে তা উল্লেখ করেন।

  1. fishExamples() এ মাছের নাম বড় করতে with() ব্যবহার করুন। কোঁকড়া ধনুর্বন্ধনীর মধ্যে, this with() পাস করা বস্তুকে বোঝায়।
fun fishExamples() {
    val fish = Fish("splashy")  // all lowercase
    with (fish.name) {
        this.capitalize()
    }
}
  1. কোন আউটপুট নেই, তাই এর চারপাশে একটি println() যোগ করুন। এবং this অন্তর্নিহিত এবং প্রয়োজন নেই, তাই আপনি এটি সরাতে পারেন।
fun fishExamples() {
    val fish = Fish("splashy")  // all lowercase
    with (fish.name) {
        println(capitalize())
    }
}
⇒ Splashy

ধাপ 3: একটি উচ্চ-অর্ডার ফাংশন তৈরি করুন

হুড অধীনে, with() একটি উচ্চ-ক্রম ফাংশন. এটি কীভাবে কাজ করে তা দেখতে, আপনি with() এর আপনার নিজের অত্যন্ত সরলীকৃত সংস্করণ তৈরি করতে পারেন যা কেবল স্ট্রিংয়ের জন্য কাজ করে।

  1. Fish.kt এ, একটি ফাংশন সংজ্ঞায়িত করুন, myWith() যা দুটি আর্গুমেন্ট নেয়। আর্গুমেন্ট হল কাজ করার বস্তু, এবং একটি ফাংশন যা অপারেশনকে সংজ্ঞায়িত করে। ফাংশনের সাথে আর্গুমেন্ট নামের কনভেনশন হল block । এই ক্ষেত্রে, যে ফাংশন কিছুই প্রদান করে না, যা Unit সাথে নির্দিষ্ট করা আছে।
fun myWith(name: String, block: String.() -> Unit) {}

myWith() ভিতরে, block() এখন String এর একটি এক্সটেনশন ফাংশন। যে ক্লাসটি বাড়ানো হচ্ছে তাকে প্রায়ই রিসিভার অবজেক্ট বলা হয়। তাই name এই ক্ষেত্রে রিসিভার বস্তু.

  1. myWith() এর বডিতে, পাস ইন ফাংশন, block() , রিসিভার অবজেক্টে প্রয়োগ করুন, name
fun myWith(name: String, block: String.() -> Unit) {
    name.block()
}
  1. fishExamples() এ, with() myWith() দিয়ে প্রতিস্থাপন করুন।
fun fishExamples() {
    val fish = Fish("splashy")  // all lowercase
    myWith (fish.name) {
        println(capitalize())
    }
}

fish.name হল নামের আর্গুমেন্ট, এবং println(capitalize()) হল ব্লক ফাংশন।

  1. প্রোগ্রাম চালান, এবং এটি আগের মত কাজ করে।
⇒ Splashy

ধাপ 4: আরও বিল্ট ইন এক্সটেনশন এক্সপ্লোর করুন

with() এক্সটেনশন ল্যাম্বডা খুবই দরকারী, এবং এটি কোটলিন স্ট্যান্ডার্ড লাইব্রেরির অংশ। এখানে আরও কয়েকটি রয়েছে যা আপনি সহজে খুঁজে পেতে পারেন: run() , apply() , এবং let()

run() ফাংশন হল একটি এক্সটেনশন যা সব ধরনের সাথে কাজ করে। এটি তার যুক্তি হিসাবে একটি ল্যাম্বডা নেয় এবং ল্যাম্বডা কার্যকর করার ফলাফল প্রদান করে।

  1. fishExamples() এ, নাম পেতে fish উপর run() কল করুন।
fish.run {
   name
}

এটি শুধু name সম্পত্তি ফেরত দেয়। আপনি একটি পরিবর্তনশীল যে বরাদ্দ করতে পারে বা এটি মুদ্রণ. এটি আসলে একটি দরকারী উদাহরণ নয়, কারণ আপনি কেবলমাত্র সম্পত্তি অ্যাক্সেস করতে পারেন, তবে run() আরও জটিল অভিব্যক্তির জন্য দরকারী হতে পারে।

apply() ফাংশন run() এর অনুরূপ, কিন্তু এটি ল্যাম্বডা-এর ফলাফলের পরিবর্তে পরিবর্তিত অবজেক্টটি প্রদান করে। এটি একটি নতুন তৈরি বস্তুতে কলিং পদ্ধতির জন্য দরকারী হতে পারে।

  1. fish একটি অনুলিপি তৈরি করুন এবং নতুন কপির নাম সেট করতে apply() কল করুন।
val fish2 = Fish(name = "splashy").apply {
     name = "sharky"
}
println(fish2.name)
⇒ sharky

let() ফাংশনটি apply() এর অনুরূপ, তবে এটি পরিবর্তনের সাথে বস্তুর একটি অনুলিপি প্রদান করে। এটি একসাথে ম্যানিপুলেশন চেইন করার জন্য দরকারী হতে পারে।

  1. fish নাম পেতে let() ব্যবহার করুন, এটিকে বড় করুন, এটিতে আরেকটি স্ট্রিং সংযুক্ত করুন, সেই ফলাফলের দৈর্ঘ্য পান, দৈর্ঘ্যে 31 যোগ করুন, তারপর ফলাফলটি প্রিন্ট করুন।
println(fish.let { it.name.capitalize()}
.let{it + "fish"}
.let{it.length}
.let{it + 31})
⇒ 42

এই উদাহরণে, it দ্বারা উল্লেখ করা বস্তুর ধরন হল Fish , তারপর String , তারপর আবার String এবং অবশেষে Int

  1. let() কল করার পরে fish প্রিন্ট করুন, এবং আপনি দেখতে পাবেন যে এটি পরিবর্তন হয়নি।
println(fish.let { it.name.capitalize()}
    .let{it + "fish"}
    .let{it.length}
    .let{it + 31})
println(fish)
⇒ 42
Fish(name=splashy)

Lambdas এবং উচ্চ-ক্রম ফাংশন সত্যিই দরকারী, কিন্তু আপনার কিছু জানা উচিত: lambdas হল বস্তু। একটি ল্যাম্বডা এক্সপ্রেশন হল একটি Function ইন্টারফেসের একটি উদাহরণ, যা নিজেই Object একটি সাবটাইপ। myWith() এর আগের উদাহরণটি বিবেচনা করুন।

myWith(fish.name) {
    capitalize()
}

Function ইন্টারফেসের একটি পদ্ধতি আছে, invoke() , যা ল্যাম্বডা এক্সপ্রেশনকে কল করার জন্য ওভাররাইড করা হয়। লম্বা হাত দিয়ে লেখা, এটি নিচের কোডের মতো দেখতে হবে।

// actually creates an object that looks like this
myWith(fish.name, object : Function1<String, Unit> {
    override fun invoke(name: String) {
        name.capitalize()
    }
})

সাধারণত এটি একটি সমস্যা নয়, কারণ অবজেক্ট তৈরি এবং কলিং ফাংশনগুলি খুব বেশি ওভারহেড, অর্থাৎ মেমরি এবং সিপিইউ সময় ব্যয় করে না। কিন্তু আপনি যদি myWith() মত কিছু সংজ্ঞায়িত করেন যা আপনি সর্বত্র ব্যবহার করেন, ওভারহেড যোগ করতে পারে।

কম্পাইলারের জন্য একটু বেশি কাজ যোগ করে রানটাইমের সময় ওভারহেড কমাতে এই কেসটি পরিচালনা করার উপায় হিসাবে Kotlin inline সরবরাহ করে। (আপনি আগের পাঠে inline সম্পর্কে কিছুটা শিখেছেন রিফাইড প্রকার সম্পর্কে কথা বলে।) একটি ফাংশনকে inline হিসাবে চিহ্নিত করার অর্থ হল যে প্রতিবার ফাংশনটি কল করা হবে, কম্পাইলার প্রকৃতপক্ষে সোর্স কোডটিকে ফাংশনটিকে "ইনলাইন" এ রূপান্তরিত করবে। অর্থাৎ, কম্পাইলার ল্যাম্বডার ভিতরের নির্দেশাবলী দিয়ে ল্যাম্বডা প্রতিস্থাপন করতে কোড পরিবর্তন করবে।

যদি উপরের উদাহরণে myWith() inline দিয়ে চিহ্নিত করা হয়:

inline myWith(fish.name) {
    capitalize()
}

এটি একটি সরাসরি কলে রূপান্তরিত হয়:

// with myWith() inline, this becomes
fish.name.capitalize()

এটি লক্ষণীয় যে বড় ফাংশন ইনলাইন করা আপনার কোডের আকার বাড়ায়, তাই এটি সহজ ফাংশনগুলির জন্য সবচেয়ে ভাল ব্যবহার করা হয় যা myWith() এর মতো অনেকবার ব্যবহার করা হয়। লাইব্রেরিগুলির এক্সটেনশন ফাংশনগুলি যা আপনি আগে শিখেছেন সেগুলি inline হিসাবে চিহ্নিত করা হয়েছে, তাই আপনাকে অতিরিক্ত বস্তু তৈরি হওয়ার বিষয়ে চিন্তা করতে হবে না৷

সিঙ্গেল অ্যাবস্ট্রাক্ট মেথড মানে শুধু একটি ইন্টারফেস যার একটি মেথড। জাভা প্রোগ্রামিং ভাষায় লিখিত API ব্যবহার করার সময় এগুলি খুব সাধারণ, তাই এটির একটি সংক্ষিপ্ত রূপ রয়েছে, SAM। কিছু উদাহরণ হল Runnable , যার একটি একক বিমূর্ত পদ্ধতি রয়েছে, run() , এবং Callable , যার একটি একক বিমূর্ত পদ্ধতি রয়েছে, call()

কোটলিনে, আপনাকে এমন ফাংশনগুলিকে কল করতে হবে যা SAM গুলিকে সর্বদা পরামিতি হিসাবে গ্রহণ করে। নীচের উদাহরণ চেষ্টা করুন.

  1. উদাহরণের ভিতরে, একটি জাভা ক্লাস, JavaRun তৈরি করুন এবং ফাইলটিতে নিম্নলিখিতটি পেস্ট করুন।
package example;

public class JavaRun {
    public static void runNow(Runnable runnable) {
        runnable.run();
    }
}

কোটলিন আপনাকে এমন একটি বস্তুকে ইনস্ট্যান্টিয়েট করতে দেয় যা object: সাথে টাইপের পূর্বে একটি ইন্টারফেস প্রয়োগ করে:। এটি SAM-এ পরামিতি পাস করার জন্য দরকারী।

  1. Fish.kt এ ফিরে আসুন, runExample() একটি ফাংশন তৈরি করুন, যা অবজেক্ট ব্যবহার করে একটি Runnable তৈরি করে object: অবজেক্টটিকে "I'm a Runnable" প্রিন্ট করে run() প্রয়োগ করা উচিত।
fun runExample() {
    val runnable = object: Runnable {
        override fun run() {
            println("I'm a Runnable")
        }
    }
}
  1. আপনার তৈরি করা অবজেক্টের সাথে JavaRun.runNow() এ কল করুন।
fun runExample() {
    val runnable = object: Runnable {
        override fun run() {
            println("I'm a Runnable")
        }
    }
    JavaRun.runNow(runnable)
}
  1. main() থেকে runExample() কল করুন এবং প্রোগ্রামটি চালান।
⇒ I'm a Runnable

কিছু প্রিন্ট করতে অনেক কাজ, কিন্তু একটি SAM কিভাবে কাজ করে তার একটি ভাল উদাহরণ। অবশ্যই, Kotlin এটি করার একটি সহজ উপায় প্রদান করে—এই কোডটিকে অনেক বেশি কম্প্যাক্ট করতে অবজেক্টের জায়গায় একটি ল্যাম্বডা ব্যবহার করুন।

  1. runExample এ বিদ্যমান কোডটি সরান, এটিকে একটি ল্যাম্বডা দিয়ে runNow() কল করতে পরিবর্তন করুন এবং প্রোগ্রামটি চালান।
fun runExample() {
    JavaRun.runNow({
        println("Passing a lambda as a Runnable")
    })
}
⇒ Passing a lambda as a Runnable
  1. আপনি শেষ প্যারামিটার কল সিনট্যাক্স ব্যবহার করে এটি আরও সংক্ষিপ্ত করতে পারেন এবং বন্ধনী থেকে মুক্তি পেতে পারেন।
fun runExample() {
    JavaRun.runNow {
        println("Last parameter is a lambda as a Runnable")
    }
}
⇒ Last parameter is a lambda as a Runnable

এটি একটি SAM এর মৌলিক বিষয়, একটি একক বিমূর্ত পদ্ধতি। আপনি প্যাটার্ন ব্যবহার করে কোডের একটি লাইন দিয়ে SAM-কে ইনস্ট্যান্ট, ওভাররাইড এবং কল করতে পারেন:
Class.singleAbstractMethod { lambda_of_override }

এই পাঠটি ল্যাম্বডাস পর্যালোচনা করেছে এবং উচ্চ-অর্ডার ফাংশন-কোটলিনের মূল অংশগুলির সাথে আরও গভীরে গেছে। আপনি টীকা এবং লেবেল বিরতি সম্পর্কেও শিখেছেন।

  • কম্পাইলার জিনিস নির্দিষ্ট করতে টীকা ব্যবহার করুন. যেমন:
    @file:JvmName("Foo")
  • আপনার কোড নেস্টেড লুপগুলির ভিতরে থেকে প্রস্থান করতে লেবেলযুক্ত বিরতিগুলি ব্যবহার করুন৷ যেমন:
    if (i > 10) break@outerLoop // breaks to outerLoop label
  • উচ্চ-অর্ডার ফাংশনগুলির সাথে মিলিত হলে ল্যাম্বডাস খুব শক্তিশালী হতে পারে।
  • ল্যাম্বডাস বস্তু। অবজেক্ট তৈরি করা এড়াতে, আপনি inline দিয়ে ফাংশনটি চিহ্নিত করতে পারেন এবং কম্পাইলার ল্যাম্বডার বিষয়বস্তু সরাসরি কোডে রাখবে।
  • সাবধানে inline ব্যবহার করুন, কিন্তু এটি আপনার প্রোগ্রাম দ্বারা সম্পদ ব্যবহার কমাতে সাহায্য করতে পারে।
  • SAM, একক বিমূর্ত পদ্ধতি, একটি সাধারণ প্যাটার্ন, এবং ল্যাম্বডাস দিয়ে সহজ করা হয়। মৌলিক প্যাটার্ন হল:
    Class.singleAbstractMethod { lamba_of_override }
  • কোটলিন স্ট্যান্ডার্ড লাইব্রেরি বিভিন্ন SAM সহ অনেক দরকারী ফাংশন প্রদান করে, তাই এতে কী আছে তা জানুন।

কোর্সে কভার করার চেয়ে কোটলিনের আরও অনেক কিছু আছে, কিন্তু আপনার নিজের কোটলিন প্রোগ্রামগুলি তৈরি করা শুরু করার জন্য আপনার কাছে এখন মৌলিক বিষয় রয়েছে। আশা করি আপনি এই অভিব্যক্তিপূর্ণ ভাষা সম্পর্কে উত্তেজিত, এবং কম কোড লেখার সময় আরও কার্যকারিতা তৈরি করার অপেক্ষায় রয়েছেন (বিশেষ করে যদি আপনি জাভা প্রোগ্রামিং ভাষা থেকে আসছেন।) অনুশীলন এবং শেখার সাথে সাথে কোটলিনের একজন বিশেষজ্ঞ হওয়ার সর্বোত্তম উপায়, তাই নিজের থেকে Kotlin সম্পর্কে অন্বেষণ এবং শিখতে থাকুন।

কোটলিন ডকুমেন্টেশন

আপনি যদি এই কোর্সে কোনো বিষয়ে আরও তথ্য চান, বা আপনি যদি আটকে যান, https://kotlinlang.org আপনার সেরা শুরুর পয়েন্ট।

কোটলিন টিউটোরিয়াল

https://try.kotlinlang.org ওয়েবসাইটটিতে Kotlin Koans নামে সমৃদ্ধ টিউটোরিয়াল রয়েছে, একটি ওয়েব-ভিত্তিক দোভাষী , এবং উদাহরণ সহ রেফারেন্স ডকুমেন্টেশনের একটি সম্পূর্ণ সেট।

উদ্যতা কোর্স

এই বিষয়ে Udacity কোর্সটি দেখতে, প্রোগ্রামারদের জন্য Kotlin Bootcamp দেখুন।

ইন্টেলিজ আইডিয়া

IntelliJ IDEA-এর জন্য ডকুমেন্টেশন জেটব্রেইন্স ওয়েবসাইটে পাওয়া যাবে।

কোটলিন স্ট্যান্ডার্ড লাইব্রেরি

কোটলিন স্ট্যান্ডার্ড লাইব্রেরি অনেক দরকারী ফাংশন প্রদান করে। আপনার নিজের ফাংশন বা ইন্টারফেস লেখার আগে, কেউ আপনার কিছু কাজ সংরক্ষণ করেছে কিনা তা দেখতে সর্বদা স্ট্যান্ডার্ড লাইব্রেরি পরীক্ষা করুন। মাঝে মাঝে আবার চেক করুন, কারণ নতুন কার্যকারিতা ঘন ঘন যোগ করা হয়।

কোটলিন টিউটোরিয়াল

https://try.kotlinlang.org ওয়েবসাইটটিতে Kotlin Koans নামে সমৃদ্ধ টিউটোরিয়াল রয়েছে, একটি ওয়েব-ভিত্তিক দোভাষী , এবং উদাহরণ সহ রেফারেন্স ডকুমেন্টেশনের একটি সম্পূর্ণ সেট।

উদ্যতা কোর্স

এই বিষয়ে Udacity কোর্সটি দেখতে, প্রোগ্রামারদের জন্য Kotlin Bootcamp দেখুন।

ইন্টেলিজ আইডিয়া

IntelliJ IDEA-এর জন্য ডকুমেন্টেশন জেটব্রেইন্স ওয়েবসাইটে পাওয়া যাবে।

এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:

  • প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
  • শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
  • হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.

প্রশিক্ষকরা এই পরামর্শগুলি যতটা কম বা যতটা চান ততটা ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।

আপনি যদি নিজে থেকে এই কোডল্যাবের মাধ্যমে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলিকে নির্দ্বিধায় ব্যবহার করুন৷

এই প্রশ্নগুলোর উত্তর দাও

প্রশ্ন 1

কোটলিনে, SAM এর অর্থ হল:

▢ নিরাপদ আর্গুমেন্ট ম্যাচিং

▢ সহজ অ্যাক্সেস পদ্ধতি

▢ একক বিমূর্ত পদ্ধতি

▢ কৌশলগত অ্যাক্সেস পদ্ধতি

প্রশ্ন 2

নিচের কোনটি কোটলিন স্ট্যান্ডার্ড লাইব্রেরি এক্সটেনশন ফাংশন নয়?

elvis()

apply()

run()

with()

প্রশ্ন 3

নিচের কোনটি কোটলিনের ল্যাম্বডাসের ক্ষেত্রে সত্য নয়?

▢ ল্যাম্বডাস হল বেনামী ফাংশন।

▢ ল্যাম্বডাস হল বস্তু যদি ইনলাইন না থাকে।

▢ ল্যাম্বডাস সম্পদ নিবিড় এবং ব্যবহার করা উচিত নয়।

▢ Lambdas অন্যান্য ফাংশন পাস করা যেতে পারে.

প্রশ্ন 4

কোটলিনে লেবেলগুলি একটি শনাক্তকারীর সাথে নির্দেশিত হয় যার পরে:

:

::

@:

@

অভিনন্দন! আপনি প্রোগ্রামার কোডল্যাবের জন্য কোটলিন বুটক্যাম্প সম্পূর্ণ করেছেন।

অন্যান্য কোডল্যাবগুলির লিঙ্ক সহ কোর্সের একটি ওভারভিউয়ের জন্য, "প্রোগ্রামারদের জন্য কোটলিন বুটক্যাম্প: কোর্সে স্বাগতম" দেখুন।