ইন

ইন্টিজার মধ্যে Rust

১টি অনুশীলনী

ইন্টিজার সম্পর্কে

ইন্টিজার হলো পূর্ণসংখ্যা। এদের কোনো ভগ্নাংশ বা দশমিক অংশ থাকে না। এগুলো মেশিনে বিটের একটি বাইনারি প্যাটার্ন হিসেবে রূপায়িত হয়।

ইন্টিজার সাইনড হতে পারে, আবার নাও হতে পারে। সাইনডনেস মানে হলো সংখ্যাটির একটি বিট নির্দিষ্ট করে রাখা, যা বোঝায় সংখ্যাটি ঋণাত্মক কি না।

প্রতিটি ইন্টিজারের একটি বিট প্রস্থ থাকে, যেটি আসলে সংখ্যাটি তৈরি করে এমন বিটের সংখ্যা। এটি ওই ইন্টিজার টাইপ দিয়ে প্রকাশ করা যায় এমন সর্বোচ্চ মানকে প্রভাবিত করে।

উদাহরণস্বরূপ, সবচেয়ে কমন ইন্টিজার টাইপগুলোর একটি হলো u8: একটি আনসাইনড, ৮-বিট ইন্টিজার। আপনি এই টাইপটিকে একটি একক বাইট হিসেবে চিনতে পারেন। এর সর্বনিম্ন মান ০ এবং সর্বোচ্চ মান ২৫৫।

Rust-এ ১২টি ইন্টিজার প্রিমিটিভ টাইপ আছে, যা বিট প্রস্থ ও সাইনডনেস অনুযায়ী ভাগ করা:

Unsigned Signed
u8 i8
u16 i16
u32 i32
u64 i64
u128 i128
usize isize

একটি ইন্টিজারের বিট প্রস্থ সবসময় u বা i-এর পরের সংখ্যা দিয়ে বোঝানো হয়। usize ও isize বিশেষ: এদের প্রস্থ টার্গেট মেশিনের একটি পয়েন্টারের সমান। এর মানে হলো, ৬৪-বিট আর্কিটেকচারে usize ও isize ৬৪ বিট চওড়া, কিন্তু ৩২-বিট আর্কিটেকচারে এগুলো ৩২ বিট চওড়া।

কোনটি ব্যবহার করা উচিত?

সাধারণভাবে, আপনার যদি কেবল কোনো একটি সংখ্যা প্রকাশ করতে হয়, তাহলে i32 ব্যবহার করুন: ৩২ বিটের রেঞ্জ যথেষ্ট প্রশস্ত, ফলে ওভারফ্লো হওয়ার সম্ভাবনা তুলনামূলকভাবে কম, আর আনসাইনড সংখ্যার চেয়ে সাইনড সংখ্যায় চমক কম থাকে। i32 আসলে C-এর long বা Java-র int-এর সমতুল্য। আপনি যদি একটি নিউমেরিক লিটারাল ব্যবহার করেন এবং টাইপ স্পষ্টভাবে অ্যানোটেট না করেন, তাহলে ডিফল্ট হিসেবে i32 ধরা হবে।

আপনি যদি বাইনারি ডেটা নিয়ে কাজ করেন, তাহলে বাইট নিয়ে কাজ করাই সবচেয়ে সহজ: &[u8] বা Vec<u8>।

Rust কালেকশনের সাইজ ও ইনডেক্সিংয়ের জন্য usize ব্যবহার করে। এর কারণ, একটি কম্পিউটার তত্ত্বগতভাবে কেবল usize::MAX বাইট মেমরি অ্যাড্রেস করতে পারে, তাই এর চেয়ে বড় কোনো ইন-মেমরি কালেকশন সম্ভব নয়। তাই আপনি যদি কালেকশন নিয়ে অনেক কাজ করেন, তাহলে usize কাজে লাগতে পারে।

আপনার ডেটা যদি ৩২-বিট ইন্টিজারে না ধরে, তাহলে ৬৪ বা ১২৮ বিটের ইন্টিজারে যাওয়ার কথা ভাবুন। আপনার ডেটা যদি ১২৮-বিট ইন্টিজারেও না ধরে, তাহলে num-bigint যেভাবে দেয়, তেমন একটি বিগ ইন্টিজার টাইপ ব্যবহার করতে পারেন।

১৬ বিটের ইন্টিজার খুব একটা কমন নয়, তবে নির্দিষ্ট কিছু মাইক্রোকন্ট্রোলারকে টার্গেট করার সময় কাজে লাগতে পারে।

আপনি যদি জানেন যে আপনার অ্যাপ্লিকেশনে বৈধ ঋণাত্মক কোনো কেস নেই, তাহলে সাইনড ইন্টিজারের বদলে আনসাইনড ইন্টিজার ব্যবহার করাই ভালো। গণনা এর একটি ভালো উদাহরণ।

ইন্টিজারের মধ্যে রূপান্তর

Rust-এ কোনো ইমপ্লিসিট নিউমেরিক কনভার্সন নেই। ইন্টিজার টাইপের মধ্যে কাস্ট করার দরকার হলে দুটি মৌলিক উপায় আছে: as কিওয়ার্ড, এবং From ও TryFrom ট্রেইট।

as কিওয়ার্ড ব্যবহার করা সহজ: expr as Type। তবে as কাস্ট ব্যবহার করার সময় মাথায় রাখতে হবে এমন কিছু সতর্কতা ও সূক্ষ্মতা আছে।

ট্রেইট-ভিত্তিক কাস্টিং একটু জটিল, কিন্তু নিরাপদ: কনভার্সন ট্রেইট কেবল যেখানে নিরাপদ সেখানেই ইমপ্লিমেন্ট করা হয়। উদাহরণস্বরূপ, i32 From<u8>, From<u16>, From<i8> এবং From<i16> ইমপ্লিমেন্ট করে: এই টাইপগুলোর যেকোনোটি দিয়ে প্রকাশযোগ্য যেকোনো মান i32-এ প্রকাশযোগ্য হওয়ার নিশ্চয়তা রয়েছে। এটি i32::from(expr) বা expr.into() আকারে ব্যবহার করা যায়, যেখানে expr ওই টাইপগুলোর একটিতে রিজলভ করে। i32 আরও TryFrom<u32>, TryFrom<u64>, TryFrom<u128>, TryFrom<usize>, TryFrom<i64>, TryFrom<i128> এবং TryFrom<isize> ইমপ্লিমেন্ট করে। এই কনভার্সনগুলো মানের উপর নির্ভর করে স্পষ্টভাবে হয় সফল হবে, নয় ওভারফ্লো করবে। এগুলো ব্যবহার করতে হলে যথাযথভাবে std::convert::TryFrom বা std::convert::TryInto ট্রেইট ইমপোর্ট করতে হবে, তারপর i32::try_from(expr) বা expr.try_into() ব্যবহার করতে হবে, যেখানে expr উপযুক্ত একটি টাইপে রিজলভ করে।

as কাস্টের বদলে ট্রেইট-ভিত্তিক কাস্টিং সাধারণত বেশি পছন্দনীয়, বিশেষ করে প্রশস্ত থেকে সংকীর্ণ টাইপে রূপান্তরের সময়। ট্রেইট-ভিত্তিক কাস্টিং as কাস্টের চেয়ে নগণ্যভাবে বেশি ব্যয়বহুল: অত্যন্ত হট লুপ ছাড়া পারফরম্যান্সের কারণে as ব্যবহার করা মূল্যবান নয়।

GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি নতুন একটি উইন্ডো বা ট্যাবে খুলবে