Smart Pointers
একটি pointer হলো একটি সাধারণ ধারণা, যা এমন একটি variable-কে বোঝায় যা মেমোরিতে থাকা কোনো একটি অ্যাড্রেস ধারণ করে। এই অ্যাড্রেসটি অন্য কোনো ডেটাকে নির্দেশ করে বা “point করে” থাকে। রাস্টে সবচেয়ে সাধারণ ধরনের pointer হলো reference, যা সম্পর্কে আপনি Chapter 4-এ জেনেছেন। Reference-কে &
চিহ্ন দিয়ে প্রকাশ করা হয় এবং এটি যে ভ্যালুকে point করে, তাকে borrow করে। ডেটাকে নির্দেশ করা ছাড়া এদের অন্য কোনো বিশেষ ক্ষমতা নেই, এবং এদের কোনো ওভারহেডও (overhead) নেই।
অন্যদিকে, Smart pointer হলো এমন ডেটা স্ট্রাকচার যা একটি pointer-এর মতোই কাজ করে, কিন্তু এর সাথে অতিরিক্ত মেটাডেটা (metadata) এবং কিছু বিশেষ ক্ষমতাও থাকে। Smart pointer-এর ধারণাটি শুধু রাস্টের জন্য নতুন নয়; এর প্রচলন C++ থেকে শুরু হয়েছিল এবং অন্যান্য ভাষাতেও এর وجود রয়েছে। রাস্টের স্ট্যান্ডার্ড লাইব্রেরিতে বিভিন্ন ধরনের smart pointer রয়েছে যা reference-এর চেয়েও বেশি কার্যকারিতা প্রদান করে। এই সাধারণ ধারণাটি বোঝার জন্য, আমরা কয়েকটি ভিন্ন ধরনের smart pointer-এর উদাহরণ দেখব, যার মধ্যে একটি হলো reference counting smart pointer। এই pointer একটি ডেটাকে একাধিক owner রাখার সুযোগ দেয়। এটি owner-এর সংখ্যা ট্র্যাক করে এবং যখন কোনো owner থাকে না, তখন ডেটাটি মুছে ফেলে।
রাস্টের ownership এবং borrowing-এর ধারণার কারণে reference এবং smart pointer-এর মধ্যে আরও একটি পার্থক্য রয়েছে: reference শুধু ডেটা borrow করে, কিন্তু অনেক ক্ষেত্রে smart pointer তার নির্দেশিত ডেটার own (মালিকানা) করে।
Smart pointer সাধারণত struct ব্যবহার করে ইমপ্লিমেন্ট (implement) করা হয়। সাধারণ struct-এর মতো নয়, smart pointer-গুলো Deref
এবং Drop
ট্রেইট (trait) ইমপ্লিমেন্ট করে। Deref
ট্রেইটটি smart pointer struct-এর একটি ইনস্ট্যান্সকে reference-এর মতো আচরণ করার সুযোগ দেয়, ফলে আপনি reference বা smart pointer উভয়ের জন্য কাজ করে এমন কোড লিখতে পারেন। Drop
ট্রেইটটি আপনাকে সেই কোডটি কাস্টমাইজ (customize) করার সুযোগ দেয়, যা smart pointer-এর ইনস্ট্যান্সটি স্কোপের (scope) বাইরে চলে গেলে রান হবে। এই অধ্যায়ে, আমরা এই দুটি ট্রেইট নিয়েই আলোচনা করব এবং দেখাব কেন এগুলো smart pointer-এর জন্য এত গুরুত্বপূর্ণ।
যেহেতু smart pointer প্যাটার্নটি রাস্ট-এ প্রায়শই ব্যবহৃত একটি সাধারণ ডিজাইন প্যাটার্ন, তাই এই অধ্যায়ে আমরা সব ধরনের smart pointer নিয়ে আলোচনা করব না। অনেক লাইব্রেরির নিজস্ব smart pointer রয়েছে, এবং আপনি চাইলে নিজের smart pointer তৈরি করতে পারেন। আমরা স্ট্যান্ডার্ড লাইব্রেরির সবচেয়ে সাধারণ smart pointer-গুলো নিয়ে আলোচনা করব:
Box<T>
, heap-এ ভ্যালু allocate করার জন্যRc<T>
, একটি reference counting টাইপ যা একাধিক ownership-এর সুযোগ দেয়Ref<T>
এবংRefMut<T>
, যাRefCell<T>
-এর মাধ্যমে অ্যাক্সেস করা হয়। এটি compile time-এর পরিবর্তে runtime-এ borrowing-এর নিয়মগুলো প্রয়োগ করে
এর পাশাপাশি, আমরা interior mutability প্যাটার্নটি নিয়েও আলোচনা করব, যেখানে একটি immutable টাইপ তার ভেতরের কোনো ভ্যালু পরিবর্তন করার জন্য একটি API প্রদান করে। আমরা reference cycle নিয়েও আলোচনা করব: এগুলো কীভাবে মেমোরি লিক (leak) করতে পারে এবং কীভাবে তা প্রতিরোধ করা যায়।
চলুন, শুরু করা যাক