Traits কী?
Rust এ traits হল একটি বৈশিষ্ট্য যা কোনো টাইপের জন্য একটি নির্দিষ্ট আচরণ বা ফাংশনালিটি সংজ্ঞায়িত করে। এটি কার্যকরভাবে interface এর মত কাজ করে, যা বিভিন্ন টাইপে একই ফাংশনালিটি যোগ করতে সাহায্য করে। একটি trait ডিফাইন করা হলে, সেটি অন্যান্য টাইপে (struct, enum) বাস্তবায়িত (implement) করা যেতে পারে, যার মাধ্যমে ঐ টাইপগুলো সেই trait এর ফাংশনগুলিকে কার্যকরভাবে ব্যবহার করতে পারে।
Custom Traits তৈরি করা
রাস্টে কাস্টম traits তৈরি করার জন্য প্রথমে trait কিওয়ার্ড ব্যবহার করে trait সংজ্ঞায়িত করতে হয়। এরপর, সেই trait এর মধ্যে এক বা একাধিক মেথড (function) নির্ধারণ করা হয়, যেগুলি ঐ trait কে বাস্তবায়িত (implement) করা টাইপে ব্যবহার করা যাবে।
উদাহরণ ১: Basic Custom Trait
এখানে আমরা একটি সাধারণ কাস্টম trait Descriptive তৈরি করব, যা একটি describe মেথড সংজ্ঞায়িত করবে।
// Trait সংজ্ঞায়িত করা
trait Descriptive {
fn describe(&self) -> String; // মেথডের সিগনেচার
}
// Struct তৈরি করা
struct Person {
name: String,
age: u32,
}
// Person এর জন্য Descriptive trait বাস্তবায়িত করা
impl Descriptive for Person {
fn describe(&self) -> String {
format!("{} is {} years old.", self.name, self.age)
}
}
fn main() {
let person = Person {
name: String::from("Alice"),
age: 30,
};
println!("{}", person.describe()); // "Alice is 30 years old."
}এখানে:
Descriptivetrait একটিdescribeমেথড সংজ্ঞায়িত করেছে, যা একটি স্ট্রিং ফেরত দেবে।Personstruct এর জন্যDescriptivetrait বাস্তবায়ন করা হয়েছে, যেখানেdescribeমেথডেnameএবংageব্যবহার করে একটি বর্ণনা তৈরি করা হয়েছে।
Custom Traits with Default Methods
রাস্টে, আপনি একটি trait এর মধ্যে ডিফল্ট মেথডও সংজ্ঞায়িত করতে পারেন। এই ডিফল্ট মেথডটি impl ব্লকে পুনরায় বাস্তবায়ন না করেও ব্যবহার করা যাবে।
উদাহরণ ২: Trait with Default Method
// Trait সংজ্ঞায়িত করা
trait Greet {
fn greet(&self) -> String {
String::from("Hello, world!") // ডিফল্ট মেথড
}
}
// Struct তৈরি করা
struct Person {
name: String,
}
// Person এর জন্য Greet trait বাস্তবায়িত করা
impl Greet for Person {
fn greet(&self) -> String {
format!("Hello, {}!", self.name) // কাস্টম মেথড বাস্তবায়ন
}
}
fn main() {
let person = Person {
name: String::from("Bob"),
};
// কাস্টম greet মেথড ব্যবহার করা
println!("{}", person.greet()); // "Hello, Bob!"
}এখানে:
Greettrait এর মধ্যে একটি ডিফল্টgreetমেথড রয়েছে, যা "Hello, world!" রিটার্ন করবে।Personstruct এর জন্য,greetমেথড কাস্টমাইজ করা হয়েছে, যেখানেnameদিয়ে একটি ব্যাক্তিগত অভ্যর্থনা বার্তা তৈরি করা হয়েছে।
Trait Bounds (Generic Types)
কাস্টম traits এর সাহায্যে আপনি generic types এর জন্য নির্দিষ্ট সীমাবদ্ধতা (bounds) তৈরি করতে পারেন। এই ধারণাটি সাধারণত generic functions বা generic structs এর ক্ষেত্রে প্রযোজ্য।
উদাহরণ ৩: Trait Bound in Generic Function
// Trait সংজ্ঞায়িত করা
trait Summarizable {
fn summarize(&self) -> String;
}
// Struct তৈরি করা
struct Article {
title: String,
content: String,
}
// Article এর জন্য Summarizable trait বাস্তবায়িত করা
impl Summarizable for Article {
fn summarize(&self) -> String {
format!("{} - {}", self.title, self.content)
}
}
// Generic ফাংশন যা trait bound ব্যবহার করবে
fn print_summary<T: Summarizable>(item: T) {
println!("{}", item.summarize());
}
fn main() {
let article = Article {
title: String::from("Rust is Awesome!"),
content: String::from("Rust provides memory safety and concurrency."),
};
print_summary(article); // "Rust is Awesome! - Rust provides memory safety and concurrency."
}এখানে:
Summarizabletrait একটিsummarizeমেথড সংজ্ঞায়িত করেছে।Articlestruct এর জন্যSummarizabletrait বাস্তবায়িত হয়েছে।print_summaryএকটি generic ফাংশন যাSummarizabletrait এর সাথে bound, অর্থাৎ যেকোনো টাইপ যেটিSummarizabletrait বাস্তবায়ন করেছে, সেটি এই ফাংশনকে আর্গুমেন্ট হিসেবে প্রদান করা যাবে।
Trait Inheritance (Trait Bounds)
রাস্টে, এক trait অন্য trait থেকে বৈশিষ্ট্য নিতে পারে, যা "trait inheritance" এর মতো কাজ করে। এটি trait bounds ব্যবহার করে করা হয়, যেখানে একটি trait অন্য trait এর method গুলি ব্যবহার করতে পারে।
উদাহরণ ৪: Trait Inheritance
// Basic trait সংজ্ঞায়িত করা
trait Speak {
fn speak(&self);
}
// আরও একটি trait তৈরি করা যা Speak এর বৈশিষ্ট্য ধারণ করবে
trait Greet: Speak {
fn greet(&self) {
println!("Hello!");
self.speak(); // Speak trait এর speak মেথড ব্যবহার
}
}
// Struct তৈরি করা
struct Person {
name: String,
}
// Person এর জন্য Speak এবং Greet trait বাস্তবায়িত করা
impl Speak for Person {
fn speak(&self) {
println!("My name is {}", self.name);
}
}
impl Greet for Person {}
fn main() {
let person = Person {
name: String::from("Alice"),
};
person.greet(); // "Hello!" এবং "My name is Alice"
}এখানে:
GreettraitটিSpeaktrait কে inherit করেছে, এবংspeakমেথডকে ব্যবহার করতে সক্ষম হয়েছে।Personstruct উভয় trait বাস্তবায়ন করেছে, এবংgreetমেথড কল করার মাধ্যমেspeakমেথডকে ব্যবহার করেছে।
সারাংশ
- Custom Traits তৈরি করার মাধ্যমে আপনি একটি নির্দিষ্ট আচরণ বা ফাংশনালিটি তৈরি করতে পারেন, যা অন্য টাইপে বাস্তবায়ন করতে পারেন।
- আপনি কাস্টম traits এর মধ্যে ডিফল্ট মেথড সংজ্ঞায়িত করতে পারেন এবং generic functions বা generic structs এ trait bounds ব্যবহার করতে পারেন।
- Trait inheritance এর মাধ্যমে এক trait অন্য trait এর বৈশিষ্ট্য গ্রহণ করতে পারে, যা কোড পুনঃব্যবহারে সহায়ক।
Read more