Kotlin-এ স্কোপ ফাংশন হল পাঁচটি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন (let, run, with, apply, also) যা একটি অবজেক্টের প্রসঙ্গে কোড ব্লক নির্বাহ করে। এগুলি অবজেক্টে অ্যাক্সেসের পদ্ধতি (it বা this-এর মাধ্যমে) এবং রিটার্ন মান (প্রসঙ্গ অবজেক্ট বা lambda ফলাফল) দ্বারা পৃথক হয়। Kotlin ডকুমেন্টেশন (2026) অনুসারে, সঠিক স্কোপ ফাংশন নির্বাচন বয়লারপ্লেট কোড 25–40% কমায়। স্কোপ ফাংশন অবজেক্ট ইনিশিয়ালাইজেশন, কনফিগারেশন এবং রূপান্তর ঘোষণামূলক শৈলীতে লিখতে সাহায্য করে।
মূল বিষয়
স্কোপ ফাংশন হল পাঁচটি ফাংশনের (let, run, with, apply, also) একটি সেট যা Kotlin স্ট্যান্ডার্ড লাইব্রেরিতে নির্মিত। প্রতিটি একটি lambda নেয় এবং অস্থায়ীভাবে স্কোপ পরিবর্তন করে যাতে lambda-এর ভিতরের কোড একটি নির্দিষ্ট অবজেক্টের প্রসঙ্গে নির্বাহিত হয়। এটি একাধিক কলের জন্য অবজেক্টের নাম পুনরাবৃত্তি করা এড়ায় এবং সম্পর্কিত অপারেশনগুলিকে একটি ব্লকে গ্রুপ করে।
দুটি মূল বৈশিষ্ট্য স্কোপ ফাংশনকে পৃথক করে: প্রসঙ্গ অবজেক্ট অ্যাক্সেসের পদ্ধতি (this বা it-এর মাধ্যমে) এবং রিটার্ন মান (প্রসঙ্গ অবজেক্ট নিজেই বা lambda ফলাফল)। this-এর মাধ্যমে অ্যাক্সেস অবজেক্টকে অন্তর্নিহিত প্রাপক করে — মেথড এবং প্রপার্টি উপসর্গ ছাড়াই কল করা হয়। it-এর মাধ্যমে অ্যাক্সেস অবজেক্টকে lambda-এর স্পষ্ট প্যারামিটার হিসেবে পাস করে। অবজেক্ট রিটার্ন করলে চেইনিং সম্ভব হয়, ফলাফল রিটার্ন করলে রূপান্তরিত মান নির্ধারণ করা যায়।
ঐতিহাসিকভাবে, স্কোপ ফাংশন ক্লাসিক Builder প্যাটার্ন এবং ইনিশিয়ালাইজেশনের জন্য অস্থায়ী ভেরিয়েবলের প্রতিস্থাপন হিসেবে আবির্ভূত হয়েছে। একটি আলাদা builder ক্লাস তৈরি করার পরিবর্তে, ডেভেলপার apply { প্রপার্টি1 = ...; প্রপার্টি2 = ... } লেখেন। এটি কোডের পরিমাণ কমায় এবং ইনিশিয়ালাইজেশন আরও পঠনযোগ্য করে। Kotlin ইকোসিস্টেমে, স্কোপ ফাংশন সমস্ত ফ্রেমওয়ার্ক এবং লাইব্রেরিতে একটি মানক ভাষা অভিধান হিসেবে ব্যবহৃত হয়।
সঠিক স্কোপ ফাংশনের নির্বাচন দুটি প্রশ্ন দ্বারা নির্ধারিত হয়: আপনি অবজেক্ট অ্যাক্সেস করতে this নাকি it ব্যবহার করতে চান, এবং আপনি অবজেক্ট নিজে নাকি lambda ফলাফল রিটার্ন করতে চান। দুটি বাইনারি বৈশিষ্ট্যের সংমিশ্রণ চারটি সম্ভাব্য বিকল্প দেয়, এবং with একটি বিশেষ স্থান দখল করে যা একমাত্র ফাংশন যা এক্সটেনশন নয়।
| ফাংশন | অ্যাক্সেস | রিটার্ন | এক্সটেনশন? | সাধারণ পরিস্থিতি |
|---|---|---|---|---|
| let | it | lambda ফলাফল | হ্যাঁ | রূপান্তর, null-পরীক্ষা |
| run | this | lambda ফলাফল | হ্যাঁ | প্রসঙ্গ সহ গণনা |
| with | this | lambda ফলাফল | না | কল গ্রুপিং |
| apply | this | প্রসঙ্গ অবজেক্ট | হ্যাঁ | প্রপার্টি ইনিশিয়ালাইজেশন |
| also | it | প্রসঙ্গ অবজেক্ট | হ্যাঁ | পার্শ্ব প্রতিক্রিয়া, লগিং |
নতুন মান রিটার্ন না করে অবজেক্ট কনফিগার করতে, apply (this-এর মাধ্যমে অ্যাক্সেস) বা also (it-এর মাধ্যমে অ্যাক্সেস) ব্যবহার করুন। অবজেক্টের উপর ভিত্তি করে নতুন মান গণনা করতে, let (it-এর মাধ্যমে অ্যাক্সেস) বা run (this-এর মাধ্যমে অ্যাক্সেস) ব্যবহার করুন। চেইন ছাড়া কল গ্রুপ করতে, with ব্যবহার করুন। এই স্কিম অনুসরণ করলে কোড Kotlin-এর সাথে পরিচিত অন্যান্য ডেভেলপারদের জন্য পূর্বানুমানযোগ্য হয়।
apply একটি স্কোপ ফাংশন যা প্রসঙ্গ অবজেক্ট রিটার্ন করে এবং this-এর মাধ্যমে এতে অ্যাক্সেস প্রদান করে। এটি তৈরি করার পরে অবজেক্টের প্রপার্টি ইনিশিয়ালাইজ করার জন্য আদর্শ টুল। apply ব্লকের ভিতরে অবজেক্টের নাম পুনরাবৃত্তি না করেই প্রপার্টি সেট করা যায়। মেথডটি নিজেই অবজেক্ট রিটার্ন করে, যা apply-কে চেইনে এম্বেড করা বা ইনিশিয়ালাইজারে ব্যবহার করার অনুমতি দেয়।
data class ServerConfig(
var host: String = "localhost",
var port: Int = 8080,
var useTls: Boolean = false
)
val config = ServerConfig().apply {
host = "api.example.com"
port = 443
useTls = true
}
লিস্টিং-এ apply this-এর মাধ্যমে সরাসরি প্রপার্টি অ্যাক্সেস করে ServerConfig কনফিগার করে (this বাদ দেওয়া হয়েছে)। apply ছাড়া config.host = ..., config.port = ... লিখতে হত — একই ভেরিয়েবলের তিনটি পুনরাবৃত্ত রেফারেন্স। অবজেক্ট রিটার্ন করলে কনফিগারেশন ফলাফল val config-এ সংরক্ষণ করা যায়। also, apply-এর বিপরীতে, it-এর মাধ্যমে অবজেক্ট পাস করে এবং পার্শ্ব প্রতিক্রিয়ার জন্য উপযুক্ত।
fun saveUser(user: User) {
validate(user).also { result ->
println("যাচাইকরণ ফলাফল: $result")
}
val savedUser = user.also {
log("Saving user ${it.id}")
database.save(it)
}
}
উদাহরণে also লগিং-এর জন্য ব্যবহৃত হয়েছে — মূল অবজেক্ট রিটার্ন করার সময়, এটি অবজেক্ট পরিবর্তন না করেই একটি পার্শ্ব প্রতিক্রিয়া (বার্তা আউটপুট) সম্পাদন করে। এটি একটি চেইন: validate(user) User রিটার্ন করে, also ফলাফল লগ করে এবং ব্যবহারকারীকে সামনে পাঠায়। also সংগ্রহে উপাদান যোগ করা বা রূপান্তর চেইনের মাঝখানে ডিবাগিং-এর জন্যও দরকারী।
let একটি স্কোপ ফাংশন যা lambda ফলাফল রিটার্ন করে এবং it-এর মাধ্যমে প্রসঙ্গ পাস করে। এটি null-নিরাপদ রূপান্তরের জন্য প্রাথমিক ফাংশন: যদি অবজেক্ট nullable হয়, তাহলে ?.let { } কম্বিনেশন শুধুমাত্র অ-শূন্য মানের জন্য ব্লক নির্বাহ করবে। let অস্থায়ী ভেরিয়েবলের স্কোপ সীমিত করতে এবং এক টাইপ থেকে অন্য টাইপে map-সদৃশ রূপান্তরের জন্যও ব্যবহৃত হয়।
fun findUser(id: Int): User?
val displayName = findUser(42)?.let { user ->
"${user.name} (${user.email})"
} ?: "Unknown user"
// সংগ্রহ রূপান্তর সহ let
val numbers = listOf("1", "2", "3")
val parsed = numbers.firstOrNull()?.let {
it.toIntOrNull()
} ?: 0
প্রথম উদাহরণে let ?. -এর মাধ্যমে কল করা হয়েছে — ব্লক শুধুমাত্র তখনই নির্বাহিত হয় যদি findUser অ-শূন্য রিটার্ন করে। Lambda it-এর মাধ্যমে user নেয় (স্পষ্টতার জন্য নাম পরিবর্তন করা যেতে পারে) এবং একটি ফরম্যাটেড স্ট্রিং রিটার্ন করে। ব্যবহারকারী না পাওয়া গেলে, Elvis অপারেটর ?: ডিফল্ট মান দেয়। দ্বিতীয় উদাহরণে let একটি স্ট্রিংকে সম্ভাব্য null সহ সংখ্যায় রূপান্তর করে।
run this-এর মাধ্যমে অ্যাক্সেস সহ let-এর অ্যানালগ, যা lambda ফলাফল রিটার্ন করে। run সেই গণনার জন্য সুবিধাজনক যেখানে অবজেক্ট প্রসঙ্গ প্রয়োজন কিন্তু নতুন মান রিটার্ন করে। অবজেক্ট ছাড়া run() কল করা (run { ... } হিসাবে) ভেরিয়েবলের জন্য একটি অস্থায়ী স্কোপ তৈরি করে। with this-এর মাধ্যমে অ্যাক্সেস সহ একটি অ-এক্সটেনশন, যা চেইন ছাড়া কল গ্রুপ করার জন্য উপযুক্ত।
// প্রসঙ্গ-চালিত গণনা হিসাবে run
val transformed = listOf(1, 2, 3).run {
filter { it > 1 }.map { it * 10 }
}
println(transformed) // [20, 30]
// কল গ্রুপ করার জন্য with
val info = with(StringBuilder()) {
append("Name: ")
append("Alice")
toString()
}
উদাহরণে তালিকার উপর run ফিল্টারিং এবং ম্যাপিং-এর ফলাফল রিটার্ন করে — রূপান্তর নিজেই, তালিকা নয়। with StringBuilder-কে আর্গুমেন্ট হিসেবে নেয় (ডটের মাধ্যমে নয়) এবং ভিতরে this-এর সাথে কাজ করে: append, append, toString। with-এর ফলাফল হল info স্ট্রিং। run এবং with-এর মধ্যে নির্বাচন প্রায়শই বিষয়ভিত্তিক, কিন্তু with তখন পছন্দনীয় যখন অবজেক্ট চেইন ছাড়া অন্য জায়গা থেকে পাস করা হয়।
with অন্যান্য স্কোপ ফাংশন থেকে আলাদা যে এটি একটি এক্সটেনশন ফাংশন নয়। এটি প্রথম আর্গুমেন্ট হিসেবে অবজেক্ট এবং দ্বিতীয় হিসেবে lambda নেয়। lambda-এর ভিতরে অবজেক্ট this-এর মাধ্যমে অ্যাক্সেসযোগ্য। with ফলাফল সংরক্ষণ না করেই অবজেক্ট মেথড কল গ্রুপ করার জন্য বা যখন একাধিক প্রপার্টি পড়ার জন্য অস্থায়ীভাবে প্রসঙ্গে “প্রবেশ” করার প্রয়োজন হয় তখন সুবিধাজনক।
val user = User("Alice", "alice@example.com", "Admin")
val summary = with(user) {
"User $name has role $role and email $email"
}
println(summary)
// UI কম্পোনেন্ট ইনিশিয়ালাইজেশনের জন্য with
with(TextView(context)) {
text = "Hello"
textSize = 18.0f
setTextColor(Color.BLUE)
}
প্রথম উদাহরণে with this-এর মাধ্যমে সরাসরি user প্রপার্টি অ্যাক্সেস করে summary স্ট্রিং গঠন করে। with ছাড়া "User ${user.name} has role ${user.role}" লিখতে হত — user-এর পুনরাবৃত্তি। দ্বিতীয় উদাহরণে with TextView কনফিগারেশন গ্রুপ করে: সমস্ত মেথড এবং প্রপার্টি পুনরাবৃত্তি ছাড়াই একটি অবজেক্টে কল করা হয়। with-এর ত্রুটি — চেইনে ব্যবহার করতে অক্ষমতা, কারণ এটি এক্সটেনশন নয় এবং প্রসঙ্গ অবজেক্ট রিটার্ন করে না।
সচরাচর জিজ্ঞাসিত প্রশ্ন
apply ব্যবহার করুন — এটি অবজেক্ট রিটার্ন করে এবং this-এর মাধ্যমে অ্যাক্সেস প্রদান করে, যা অবজেক্টের নাম পুনরাবৃত্তি না করেই প্রপার্টি সেট করতে দেয়। also উপযুক্ত যদি অবজেক্ট প্রপার্টি থেকে আলাদা করার জন্য স্পষ্ট it প্যারামিটারের প্রয়োজন হয়।
let it (স্পষ্ট প্যারামিটার) এর মাধ্যমে প্রসঙ্গ পাস করে, run — this (অন্তর্নিহিত প্রাপক) এর মাধ্যমে। let null-পরীক্ষা এবং রূপান্তরের জন্য সুবিধাজনক, run — প্রসঙ্গ সহ গণনার জন্য। উভয়ই lambda ফলাফল রিটার্ন করে।
with এক্সটেনশন নয় — এটি আর্গুমেন্ট হিসেবে অবজেক্ট নেয়। with ব্যবহার করুন কল গ্রুপ করতে যখন চেইনের প্রয়োজন নেই। apply একটি এক্সটেনশন যা অবজেক্ট রিটার্ন করে, ইনিশিয়ালাইজার এবং builder প্যাটার্নে সুবিধাজনক।
হ্যাঁ, কিন্তু this সম্পর্কে সতর্ক থাকুন — নেস্টেড this বিভ্রান্তি তৈরি করে। নেস্টেড প্রসঙ্গের জন্য স্পষ্ট নাম সহ let বা also ব্যবহার করুন যাতে বাহ্যিক অবজেক্ট উল্লেখ করার সময় অস্পষ্টতা এড়ানো যায়।
সমস্ত স্কোপ ফাংশন inline, তাই এগুলি অজ্ঞাত ক্লাস থেকে ওভারহেড তৈরি করে না। এগুলির মধ্যে কার্যকারিতার পার্থক্য নগণ্য। নির্বাচন পঠনযোগ্যতা এবং নিয়মের উপর ভিত্তি করে হওয়া উচিত, গতির উপর নয়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন