panic!
নাকি panic!
নয় (To panic!
or Not to panic!
)
তাহলে আপনি কীভাবে সিদ্ধান্ত নেবেন যে কখন আপনার panic!
কল করা উচিত এবং কখন Result
রিটার্ন করা উচিত? যখন কোড প্যানিক করে, তখন পুনরুদ্ধার করার কোনো উপায় থাকে না। আপনি যেকোনো এরর পরিস্থিতির জন্য panic!
কল করতে পারেন, পুনরুদ্ধার করার কোনো সম্ভাব্য উপায় থাকুক বা না থাকুক, কিন্তু তখন আপনি কলিং কোডের পক্ষে সিদ্ধান্ত নিচ্ছেন যে পরিস্থিতিটি পুনরুদ্ধারযোগ্য নয়। আপনি যখন একটি Result
মান রিটার্ন করতে পছন্দ করেন, তখন আপনি কলিং কোডকে অপশন দেন। কলিং কোডটি তার পরিস্থিতির জন্য উপযুক্ত উপায়ে পুনরুদ্ধার করার চেষ্টা করতে পারে, অথবা এটি সিদ্ধান্ত নিতে পারে যে এই ক্ষেত্রে একটি Err
মান পুনরুদ্ধারযোগ্য নয়, তাই এটি panic!
কল করতে পারে এবং আপনার পুনরুদ্ধারযোগ্য এররটিকে একটি পুনরুদ্ধার অযোগ্য এররে পরিণত করতে পারে। অতএব, Result
রিটার্ন করা একটি ভাল ডিফল্ট পছন্দ যখন আপনি এমন একটি ফাংশন সংজ্ঞায়িত করছেন যা ব্যর্থ হতে পারে।
উদাহরণ, প্রোটোটাইপ কোড এবং পরীক্ষার মতো পরিস্থিতিতে, Result
রিটার্ন করার পরিবর্তে প্যানিক করে এমন কোড লেখাই বেশি উপযুক্ত। আসুন অনুসন্ধান করি কেন, তারপর এমন পরিস্থিতি নিয়ে আলোচনা করি যেখানে কম্পাইলার বলতে পারে না যে ব্যর্থতা অসম্ভব, কিন্তু আপনি একজন মানুষ হিসাবে পারেন। চ্যাপ্টারটি লাইব্রেরি কোডে প্যানিক করতে হবে কিনা তা সিদ্ধান্ত নেওয়ার বিষয়ে কিছু সাধারণ নির্দেশিকা দিয়ে শেষ হবে।
উদাহরণ, প্রোটোটাইপ কোড এবং পরীক্ষা (Examples, Prototype Code, and Tests)
আপনি যখন কোনো ধারণা বোঝানোর জন্য একটি উদাহরণ লিখছেন, তখন শক্তিশালী এরর-হ্যান্ডলিং কোড অন্তর্ভুক্ত করা উদাহরণটিকে কম স্পষ্ট করে তুলতে পারে। উদাহরণগুলোতে, এটি বোঝা যায় যে unwrap
-এর মতো একটি মেথডের কল যা প্যানিক করতে পারে, তা হল আপনি যেভাবে আপনার অ্যাপ্লিকেশনটিকে এররগুলো হ্যান্ডেল করতে চান তার জন্য একটি স্থানধারক (placeholder), যা আপনার কোডের বাকি অংশ কী করছে তার উপর ভিত্তি করে ভিন্ন হতে পারে।
একইভাবে, unwrap
এবং expect
মেথডগুলো প্রোটোটাইপ করার সময় খুব সুবিধাজনক, আপনি কীভাবে এররগুলো হ্যান্ডেল করবেন তা সিদ্ধান্ত নেওয়ার আগে। আপনি যখন আপনার প্রোগ্রামটিকে আরও শক্তিশালী করার জন্য প্রস্তুত হবেন তখন তারা আপনার কোডে পরিষ্কার মার্কার রেখে যায়।
যদি একটি টেস্টে একটি মেথড কল ব্যর্থ হয়, তাহলে আপনি চাইবেন পুরো টেস্টটি ব্যর্থ হোক, এমনকী যদি সেই মেথডটি পরীক্ষার অধীনে থাকা কার্যকারিতা নাও হয়। যেহেতু panic!
হল একটি টেস্টকে ব্যর্থ হিসাবে চিহ্নিত করার উপায়, তাই unwrap
বা expect
কল করা ঠিক সেটাই ঘটা উচিত।
যেসব ক্ষেত্রে কম্পাইলারের চেয়ে আপনার কাছে বেশি তথ্য রয়েছে (Cases in Which You Have More Information Than the Compiler)
আপনি যখন unwrap
বা expect
কল করেন তখনও এটি উপযুক্ত হবে যখন আপনার কাছে অন্য কোনো লজিক থাকে যা নিশ্চিত করে যে Result
-এর একটি Ok
মান থাকবে, কিন্তু লজিকটি কম্পাইলার বোঝার মতো কিছু নয়। আপনার কাছে তখনও একটি Result
মান থাকবে যা আপনাকে হ্যান্ডেল করতে হবে: আপনি যে অপারেশনটি কল করছেন সেটি সাধারণভাবে ব্যর্থ হওয়ার সম্ভাবনা রয়েছে, যদিও এটি আপনার নির্দিষ্ট পরিস্থিতিতে যুক্তিসঙ্গতভাবে অসম্ভব। আপনি যদি ম্যানুয়ালি কোডটি পরিদর্শন করে নিশ্চিত করতে পারেন যে আপনার কখনই একটি Err
ভেরিয়েন্ট থাকবে না, তাহলে unwrap
কল করা সম্পূর্ণভাবে গ্রহণযোগ্য এবং expect
-এর টেক্সটে আপনার কেন কখনই একটি Err
ভেরিয়েন্ট থাকবে না বলে মনে করেন তার কারণ নথিভুক্ত করা আরও ভাল। এখানে একটি উদাহরণ দেওয়া হল:
fn main() { use std::net::IpAddr; let home: IpAddr = "127.0.0.1" .parse() .expect("Hardcoded IP address should be valid"); }
আমরা একটি হার্ডকোডেড স্ট্রিং পার্স করে একটি IpAddr
ইন্সট্যান্স তৈরি করছি। আমরা দেখতে পাচ্ছি যে 127.0.0.1
হল একটি বৈধ IP অ্যাড্রেস, তাই এখানে expect
ব্যবহার করা গ্রহণযোগ্য। যাইহোক, একটি হার্ডকোডেড, বৈধ স্ট্রিং থাকা parse
মেথডের রিটার্ন টাইপ পরিবর্তন করে না: আমরা এখনও একটি Result
মান পাই এবং কম্পাইলার এখনও আমাদের Result
হ্যান্ডেল করতে বাধ্য করবে যেন Err
ভেরিয়েন্ট একটি সম্ভাবনা, কারণ কম্পাইলার এতটা স্মার্ট নয় যে এটি দেখতে পায় যে এই স্ট্রিংটি সর্বদাই একটি বৈধ IP অ্যাড্রেস। যদি IP অ্যাড্রেসের স্ট্রিংটি প্রোগ্রামে হার্ডকোড করার পরিবর্তে একজন ব্যবহারকারীর কাছ থেকে আসে এবং সেইজন্য ব্যর্থতার সম্ভাবনা থাকে, তাহলে আমাদের অবশ্যই আরও শক্তিশালী উপায়ে Result
হ্যান্ডেল করতে হবে। এই IP অ্যাড্রেসটি হার্ডকোড করা হয়েছে এই ধারণাটি উল্লেখ করা ভবিষ্যতে আমাদের expect
-কে আরও ভাল এরর-হ্যান্ডলিং কোডে পরিবর্তন করতে উৎসাহিত করবে, যদি আমাদের পরিবর্তে অন্য কোনো উৎস থেকে IP অ্যাড্রেস পেতে হয়।
এরর হ্যান্ডলিংয়ের জন্য নির্দেশিকা (Guidelines for Error Handling)
আপনার কোড প্যানিক করা বাঞ্ছনীয় যখন এটি সম্ভব যে আপনার কোডটি খারাপ অবস্থায় শেষ হতে পারে। এই প্রসঙ্গে, একটি খারাপ অবস্থা (bad state) হল যখন কিছু অনুমান, গ্যারান্টি, চুক্তি বা ইনভেরিয়েন্ট (invariant) ভেঙে যায়, যেমন যখন অবৈধ মান, অসঙ্গতিপূর্ণ মান বা অনুপস্থিত মান আপনার কোডে পাস করা হয়—এছাড়াও নিম্নলিখিত এক বা একাধিক:
- খারাপ অবস্থাটি এমন কিছু যা অপ্রত্যাশিত, এমন কিছুর বিপরীতে যা মাঝে মাঝে ঘটার সম্ভাবনা রয়েছে, যেমন একজন ব্যবহারকারী ভুল ফর্ম্যাটে ডেটা প্রবেশ করানো।
- এই পয়েন্টের পরে আপনার কোডটিকে এই খারাপ অবস্থায় না থাকার উপর নির্ভর করতে হবে, প্রতিটি ধাপে সমস্যার জন্য পরীক্ষা করার পরিবর্তে।
- আপনি যে টাইপগুলো ব্যবহার করছেন তাতে এই তথ্যটি এনকোড করার কোনো ভাল উপায় নেই। আমরা চ্যাপ্টার 18-এ “স্টেট এবং আচরণকে টাইপ হিসাবে এনকোড করা”-তে এর একটি উদাহরণ নিয়ে কাজ করব।
যদি কেউ আপনার কোড কল করে এবং এমন মান পাস করে যা অর্থবোধক নয়, তাহলে আপনি যদি পারেন তবে একটি এরর রিটার্ন করা সবচেয়ে ভাল যাতে লাইব্রেরির ব্যবহারকারী সিদ্ধান্ত নিতে পারে যে তারা সেই ক্ষেত্রে কী করতে চায়। যাইহোক, যে ক্ষেত্রগুলোতে চালিয়ে যাওয়া অনিরাপদ বা ক্ষতিকারক হতে পারে, সেখানে panic!
কল করা এবং আপনার লাইব্রেরি ব্যবহার করা ব্যক্তিকে তাদের কোডের বাগ সম্পর্কে সতর্ক করা সবচেয়ে ভাল হতে পারে যাতে তারা ডেভেলপমেন্টের সময় এটি ঠিক করতে পারে। একইভাবে, আপনি যদি এক্সটার্নাল কোড কল করেন যা আপনার নিয়ন্ত্রণের বাইরে এবং এটি একটি অবৈধ অবস্থা রিটার্ন করে যা আপনার ঠিক করার কোনো উপায় নেই, তাহলে panic!
প্রায়শই উপযুক্ত।
তবে, যখন ব্যর্থতা প্রত্যাশিত হয়, তখন একটি panic!
কল করার চেয়ে Result
রিটার্ন করা আরও উপযুক্ত। উদাহরণগুলোর মধ্যে রয়েছে একটি পার্সারকে বিকৃত ডেটা দেওয়া বা একটি HTTP অনুরোধ একটি স্ট্যাটাস রিটার্ন করা যা নির্দেশ করে যে আপনি একটি রেট লিমিটে পৌঁছে গেছেন। এই ক্ষেত্রগুলোতে, একটি Result
রিটার্ন করা ইঙ্গিত দেয় যে ব্যর্থতা একটি প্রত্যাশিত সম্ভাবনা যা কলিং কোডকে কীভাবে হ্যান্ডেল করতে হবে তা অবশ্যই সিদ্ধান্ত নিতে হবে।
যখন আপনার কোড এমন একটি অপারেশন করে যা অবৈধ মান ব্যবহার করে কল করা হলে একজন ব্যবহারকারীকে ঝুঁকিতে ফেলতে পারে, তখন আপনার কোড প্রথমে মানগুলো বৈধ কিনা তা যাচাই করা উচিত এবং যদি মানগুলো বৈধ না হয় তবে প্যানিক করা উচিত। এটি বেশিরভাগ নিরাপত্তার কারণে: অবৈধ ডেটাতে কাজ করার চেষ্টা করা আপনার কোডকে দুর্বলতার দিকে প্রকাশ করতে পারে। আপনি যদি একটি আউট-অফ-বাউন্ডস মেমরি অ্যাক্সেসের চেষ্টা করেন তবে স্ট্যান্ডার্ড লাইব্রেরি panic!
কল করার এটি প্রধান কারণ: বর্তমান ডেটা স্ট্রাকচারের অন্তর্গত নয় এমন মেমরি অ্যাক্সেস করার চেষ্টা করা একটি সাধারণ নিরাপত্তা সমস্যা। ফাংশনগুলোতে প্রায়শই চুক্তি (contracts) থাকে: ইনপুটগুলো নির্দিষ্ট প্রয়োজনীয়তা পূরণ করলেই তাদের আচরণ গ্যারান্টিযুক্ত হয়। চুক্তি লঙ্ঘন হলে প্যানিক করা অর্থবোধক কারণ একটি চুক্তি লঙ্ঘন সর্বদাই একটি কলার-সাইড বাগ নির্দেশ করে এবং এটি এমন কোনো ধরনের এরর নয় যা আপনি চান যে কলিং কোডটিকে স্পষ্টতই হ্যান্ডেল করতে হবে। আসলে, কলিং কোডের পুনরুদ্ধার করার কোনো যুক্তিসঙ্গত উপায় নেই; কলিং প্রোগ্রামারদের কোড ঠিক করতে হবে। একটি ফাংশনের জন্য চুক্তিগুলো, বিশেষ করে যখন একটি লঙ্ঘন প্যানিকের কারণ হবে, ফাংশনের জন্য API ডকুমেন্টেশনে ব্যাখ্যা করা উচিত।
যাইহোক, আপনার সমস্ত ফাংশনে প্রচুর এরর চেক থাকা শব্দবহুল এবং বিরক্তিকর হবে। সৌভাগ্যবশত, আপনি আপনার জন্য অনেকগুলি চেক করতে Rust-এর টাইপ সিস্টেম (এবং এইভাবে কম্পাইলার দ্বারা করা টাইপ চেকিং) ব্যবহার করতে পারেন। যদি আপনার ফাংশনে একটি প্যারামিটার হিসাবে একটি নির্দিষ্ট টাইপ থাকে, তাহলে আপনি আপনার কোডের লজিকের সাথে এগিয়ে যেতে পারেন, এটি জেনে যে কম্পাইলার ইতিমধ্যেই নিশ্চিত করেছে যে আপনার কাছে একটি বৈধ মান রয়েছে। উদাহরণস্বরূপ, যদি আপনার একটি টাইপ থাকে Option
-এর পরিবর্তে, তাহলে আপনার প্রোগ্রামটি কিছু না থাকার পরিবর্তে কিছু থাকার আশা করে। আপনার কোডটিকে তখন Some
এবং None
ভেরিয়েন্টগুলোর জন্য দুটি ক্ষেত্র হ্যান্ডেল করতে হবে না: এটির শুধুমাত্র একটি ক্ষেত্র থাকবে যেখানে অবশ্যই একটি মান থাকবে। আপনার ফাংশনে কিছুই পাস করার চেষ্টা করা কোড কম্পাইল হবে না, তাই আপনার ফাংশনকে রানটাইমে সেই ক্ষেত্রের জন্য পরীক্ষা করতে হবে না। আরেকটি উদাহরণ হল একটি আনসাইনড ইন্টিজার টাইপ যেমন u32
ব্যবহার করা, যা নিশ্চিত করে যে প্যারামিটারটি কখনই নেতিবাচক নয়।
বৈধতার জন্য কাস্টম টাইপ তৈরি করা (Creating Custom Types for Validation)
আসুন Rust-এর টাইপ সিস্টেম ব্যবহার করার ধারণাটি আরও এক ধাপ এগিয়ে নিয়ে যাই যাতে আমরা একটি বৈধ মান নিশ্চিত করি এবং বৈধতার জন্য একটি কাস্টম টাইপ তৈরি করার দিকে নজর দিই। চ্যাপ্টার ২-এর অনুমান করার গেমটি স্মরণ করুন যেখানে আমাদের কোড ব্যবহারকারীকে 1 থেকে 100-এর মধ্যে একটি সংখ্যা অনুমান করতে বলেছিল। আমরা আমাদের গোপন সংখ্যার সাথে এটি পরীক্ষা করার আগে ব্যবহারকারীর অনুমান সেই সংখ্যাগুলোর মধ্যে ছিল কিনা তা আমরা কখনই যাচাই করিনি; আমরা শুধুমাত্র যাচাই করেছি যে অনুমানটি ধনাত্মক ছিল। এই ক্ষেত্রে, পরিণতিগুলো খুব ভয়াবহ ছিল না: আমাদের "Too high" বা "Too low"-এর আউটপুট এখনও সঠিক হবে। কিন্তু ব্যবহারকারীকে বৈধ অনুমানের দিকে পরিচালিত করা এবং ব্যবহারকারী যখন সীমার বাইরের কোনো সংখ্যা অনুমান করে তার পরিবর্তে যখন ব্যবহারকারী, উদাহরণস্বরূপ, অক্ষরের টাইপ করে তখন ভিন্ন আচরণ করা একটি দরকারী উন্নতি হবে।
এটি করার একটি উপায় হল অনুমানটিকে শুধুমাত্র একটি u32
-এর পরিবর্তে একটি i32
হিসাবে পার্স করা যাতে সম্ভাব্য নেতিবাচক সংখ্যাগুলোর অনুমতি দেওয়া যায় এবং তারপর সংখ্যাটি সীমার মধ্যে আছে কিনা তার জন্য একটি চেক যোগ করা, এইভাবে:
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
loop {
// --snip--
println!("Please input your guess.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: i32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
if guess < 1 || guess > 100 {
println!("The secret number will be between 1 and 100.");
continue;
}
match guess.cmp(&secret_number) {
// --snip--
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
if
এক্সপ্রেশনটি পরীক্ষা করে যে আমাদের মান সীমার বাইরে কিনা, ব্যবহারকারীকে সমস্যা সম্পর্কে বলে এবং লুপের পরবর্তী পুনরাবৃত্তি শুরু করতে এবং আরেকটি অনুমানের জন্য জিজ্ঞাসা করতে continue
কল করে। if
এক্সপ্রেশনের পরে, আমরা guess
এবং গোপন সংখ্যার মধ্যে তুলনা চালিয়ে যেতে পারি, এটি জেনে যে guess
1 এবং 100-এর মধ্যে রয়েছে।
যাইহোক, এটি একটি আদর্শ সমাধান নয়: যদি এটি একেবারে গুরুত্বপূর্ণ হয় যে প্রোগ্রামটি শুধুমাত্র 1 থেকে 100-এর মধ্যে মানগুলোর উপর কাজ করে এবং এটির অনেক ফাংশনে এই প্রয়োজনীয়তা থাকে, তাহলে প্রতিটি ফাংশনে এইরকম একটি চেক থাকা ক্লান্তিকর হবে (এবং পারফরম্যান্সকে প্রভাবিত করতে পারে)।
পরিবর্তে, আমরা একটি নতুন টাইপ তৈরি করতে পারি এবং সর্বত্র বৈধতা পুনরাবৃত্তি করার পরিবর্তে টাইপের একটি ইন্সট্যান্স তৈরি করার জন্য একটি ফাংশনে বৈধতা রাখতে পারি। এইভাবে, ফাংশনগুলোর জন্য তাদের সিগনেচারে নতুন টাইপ ব্যবহার করা এবং তারা যে মানগুলো গ্রহণ করে সেগুলো আত্মবিশ্বাসের সাথে ব্যবহার করা নিরাপদ। Listing 9-13 একটি Guess
টাইপ সংজ্ঞায়িত করার একটি উপায় দেখায় যা শুধুমাত্র তখনই Guess
-এর একটি ইন্সট্যান্স তৈরি করবে যদি new
ফাংশনটি 1 থেকে 100-এর মধ্যে একটি মান পায়।
#![allow(unused)] fn main() { pub struct Guess { value: i32, } impl Guess { pub fn new(value: i32) -> Guess { if value < 1 || value > 100 { panic!("Guess value must be between 1 and 100, got {value}."); } Guess { value } } pub fn value(&self) -> i32 { self.value } } }
প্রথমে আমরা Guess
নামে একটি স্ট্রাকট সংজ্ঞায়িত করি যাতে value
নামে একটি ফিল্ড রয়েছে যা একটি i32
ধারণ করে। এখানেই সংখ্যাটি সংরক্ষণ করা হবে।
তারপর আমরা Guess
-এ new
নামে একটি অ্যাসোসিয়েটেড ফাংশন ইমপ্লিমেন্ট করি যা Guess
মানগুলোর ইন্সট্যান্স তৈরি করে। new
ফাংশনটি i32
টাইপের value
নামক একটি প্যারামিটার নিতে এবং একটি Guess
রিটার্ন করার জন্য সংজ্ঞায়িত করা হয়েছে। new
ফাংশনের বডির কোডটি value
পরীক্ষা করে নিশ্চিত করে যে এটি 1 থেকে 100-এর মধ্যে রয়েছে। যদি value
এই পরীক্ষায় উত্তীর্ণ না হয়, তাহলে আমরা একটি panic!
কল করি, যা কলিং কোডটি লিখছেন এমন প্রোগ্রামারকে সতর্ক করবে যে তাদের একটি বাগ রয়েছে যা তাদের ঠিক করতে হবে, কারণ এই সীমার বাইরের একটি value
সহ একটি Guess
তৈরি করা Guess::new
যে চুক্তির উপর নির্ভর করছে তা লঙ্ঘন করবে। যে পরিস্থিতিতে Guess::new
প্যানিক করতে পারে তা এর পাবলিক-ফেসিং API ডকুমেন্টেশনে আলোচনা করা উচিত; আমরা চ্যাপ্টার 14-এ আপনার তৈরি করা API ডকুমেন্টেশনে panic!
-এর সম্ভাবনা নির্দেশ করে এমন ডকুমেন্টেশন কনভেনশনগুলো কভার করব। যদি value
পরীক্ষায় উত্তীর্ণ হয়, তাহলে আমরা value
প্যারামিটারে সেট করা এর value
ফিল্ড সহ একটি নতুন Guess
তৈরি করি এবং Guess
রিটার্ন করি।
এরপর, আমরা value
নামে একটি মেথড ইমপ্লিমেন্ট করি যা self
ধার করে, অন্য কোনো প্যারামিটার নেই এবং একটি i32
রিটার্ন করে। এই ধরনের মেথডকে কখনও কখনও গেটার (getter) বলা হয় কারণ এর উদ্দেশ্য হল এর ফিল্ডগুলো থেকে কিছু ডেটা পাওয়া এবং তা রিটার্ন করা। এই পাবলিক মেথডটি প্রয়োজনীয় কারণ Guess
স্ট্রাকটের value
ফিল্ডটি প্রাইভেট। value
ফিল্ডটি প্রাইভেট হওয়া গুরুত্বপূর্ণ যাতে Guess
স্ট্রাকট ব্যবহার করা কোড সরাসরি value
সেট করার অনুমতি না পায়: মডিউলের বাইরের কোডকে অবশ্যই Guess
-এর একটি ইন্সট্যান্স তৈরি করতে Guess::new
ফাংশন ব্যবহার করতে হবে, এইভাবে এটি নিশ্চিত করে যে Guess
-এর এমন কোনো value
থাকার কোনো উপায় নেই যা Guess::new
ফাংশনের শর্তগুলো দ্বারা পরীক্ষা করা হয়নি।
একটি ফাংশন যার একটি প্যারামিটার রয়েছে বা শুধুমাত্র 1 থেকে 100-এর মধ্যে সংখ্যা রিটার্ন করে, তারপর তার সিগনেচারে ঘোষণা করতে পারে যে এটি একটি i32
-এর পরিবর্তে একটি Guess
নেয় বা রিটার্ন করে এবং এর বডিতে কোনো অতিরিক্ত চেক করার প্রয়োজন হবে না।
সারসংক্ষেপ (Summary)
Rust-এর এরর-হ্যান্ডলিং ফিচারগুলো আপনাকে আরও শক্তিশালী কোড লিখতে সাহায্য করার জন্য ডিজাইন করা হয়েছে। panic!
ম্যাক্রো সংকেত দেয় যে আপনার প্রোগ্রামটি এমন একটি অবস্থায় রয়েছে যা এটি হ্যান্ডেল করতে পারে না এবং আপনাকে অবৈধ বা ভুল মান নিয়ে এগিয়ে যাওয়ার চেষ্টা করার পরিবর্তে প্রক্রিয়াটি বন্ধ করতে দেয়। Result
এনাম Rust-এর টাইপ সিস্টেম ব্যবহার করে নির্দেশ করে যে অপারেশনগুলো এমনভাবে ব্যর্থ হতে পারে যা থেকে আপনার কোড পুনরুদ্ধার করতে পারে। আপনি আপনার কোডকে কল করা কোডকে জানাতে Result
ব্যবহার করতে পারেন যে এটিকে সম্ভাব্য সাফল্য বা ব্যর্থতা উভয়ই হ্যান্ডেল করতে হবে। উপযুক্ত পরিস্থিতিতে panic!
এবং Result
ব্যবহার করা অনিবার্য সমস্যার মুখে আপনার কোডকে আরও নির্ভরযোগ্য করে তুলবে।
এখন আপনি দেখেছেন যে স্ট্যান্ডার্ড লাইব্রেরি কীভাবে Option
এবং Result
এনামগুলোর সাথে জেনেরিক ব্যবহার করে, আমরা জেনেরিকগুলো কীভাবে কাজ করে এবং আপনি কীভাবে আপনার কোডে সেগুলো ব্যবহার করতে পারেন সে সম্পর্কে কথা বলব।