Generics কী এবং কিভাবে কাজ করে
Generics হলো একটি শক্তিশালী ফিচার যা কটলিনসহ অনেক প্রোগ্রামিং ভাষায় ব্যবহৃত হয়। এটি একটি ক্লাস, ইন্টারফেস, বা ফাংশনে টাইপ প্যারামিটার ব্যবহার করে, যাতে একই কোড বিভিন্ন ডেটা টাইপের সাথে কাজ করতে পারে। Generics কোডের পুনঃব্যবহারযোগ্যতা বৃদ্ধি করে এবং টাইপ সেফটি নিশ্চিত করে। নিচে Generics-এর ব্যাখ্যা, সুবিধা এবং কিভাবে কাজ করে তা বিস্তারিতভাবে আলোচনা করা হলো।
১. Generics কী?
Generics হল টাইপ প্যারামিটার ব্যবহার করে কোড লেখার একটি পদ্ধতি। এটি বিশেষভাবে প্রয়োগ করা হয় যখন আপনি একটি ফাংশন বা ডেটা স্ট্রাকচার তৈরি করছেন যা বিভিন্ন টাইপের ডেটার সাথে কাজ করতে পারে।
উদাহরণ:
class Box<T>(var item: T) {
fun getItem(): T {
return item
}
}
fun main() {
val intBox = Box(123)
println(intBox.getItem()) // আউটপুট: 123
val stringBox = Box("Hello, Kotlin!")
println(stringBox.getItem()) // আউটপুট: Hello, Kotlin!
}
ব্যাখ্যা:
- এখানে
Boxক্লাসটি একটি টাইপ প্যারামিটারTগ্রহণ করে, যাitemপ্রপার্টির টাইপ হতে পারে।Boxক্লাসের বিভিন্ন ইনস্ট্যান্স তৈরি করা হয়েছেIntএবংStringটাইপের জন্য।
২. Generics এর সুবিধা
i) Type Safety
Generics কোডে টাইপ নিরাপত্তা নিশ্চিত করে, কারণ এটি রানটাইমে টাইপ সম্পর্কিত সমস্যা কমায়।
fun <T> printList(items: List<T>) {
for (item in items) {
println(item)
}
}
ব্যাখ্যা:
- এখানে
printListএকটি generic ফাংশন, যা যে কোনো টাইপের লিস্ট গ্রহণ করে।
ii) Code Reusability
Generics ব্যবহার করে একটি ফাংশন বা ক্লাস একাধিক টাইপের সাথে কাজ করতে পারে, যা কোডের পুনঃব্যবহারযোগ্যতা বাড়ায়।
iii) Elimination of Type Casting
Generics ব্যবহার করে টাইপ কাস্টিংয়ের প্রয়োজনীয়তা কমে যায়।
val stringList: List<String> = listOf("A", "B", "C")
// কোন কাস্টিংয়ের প্রয়োজন নেই
৩. Variance in Generics
Generics-এ variance টাইপ প্যারামিটারগুলোর ইনহেরিটেন্স সম্পর্কিত। এটি প্রধানত তিন ধরনের:
i) Covariance (out)
Covariance আপনাকে একটি টাইপ প্যারামিটারকে এমনভাবে ব্যবহার করতে দেয় যাতে আপনি সাবটাইপগুলি ব্যবহার করতে পারেন।
class Box<out T>(val item: T)
fun main() {
val box: Box<Number> = Box(123) // Covariance allows this
val intBox: Box<Int> = box // Box<Int> can be assigned from Box<Number>
}
ব্যাখ্যা:
- এখানে
Box<out T>ব্যবহার করা হয়েছে, যা নির্দেশ করে যেTটাইপ কেবল আউটপুট হিসাবে ব্যবহৃত হবে।
ii) Contravariance (in)
Contravariance আপনাকে টাইপ প্যারামিটারকে ইনপুট হিসাবে ব্যবহার করতে দেয়, যাতে আপনি সুপারটাইপগুলি ব্যবহার করতে পারেন।
class Printer<in T> {
fun print(item: T) {
println(item)
}
}
fun main() {
val printer: Printer<Any> = Printer<Int>() // Printer<Int> can be assigned to Printer<Any>
printer.print(123)
}
ব্যাখ্যা:
- এখানে
Printer<in T>ব্যবহার করা হয়েছে, যা নির্দেশ করে যেTটাইপ কেবল ইনপুট হিসাবে ব্যবহৃত হবে।
iii) Non-variance (No Keyword)
Non-variance হলো যখন আপনি টাইপ প্যারামিটারকে neither in nor out হিসাবে ঘোষণা করেন। এটি টাইপ নিরাপত্তা বাড়ায়।
৪. Constraints on Generics
কখনও কখনও, আপনি চান যে একটি টাইপ প্যারামিটার অবশ্যই একটি নির্দিষ্ট ক্লাস বা ইন্টারফেসের সাবটাইপ হতে হবে। এটি করতে, আপনি where কিওয়ার্ড ব্যবহার করতে পারেন।
fun <T> printIfNotNull(item: T?) where T : Any {
item?.let { println(it) }
}
ব্যাখ্যা:
- এখানে
T : Anyনির্দেশ করে যেTঅবশ্যইAnyটাইপের সাবটাইপ হতে হবে।
উপসংহার
Generics কটলিনের একটি শক্তিশালী ফিচার, যা কোডের পুনঃব্যবহারযোগ্যতা, টাইপ নিরাপত্তা এবং কার্যকারিতা বাড়ায়। এটি আপনাকে বিভিন্ন টাইপের ডেটার সাথে কাজ করতে দেয়, যা প্রোগ্রামিংকে আরও কার্যকর এবং সংগঠিত করে তোলে।
Read more