"ফ্যাট পয়েন্টার" শব্দটি গতিশীল আকারের ধরণের (ডিএসটি) - স্লাইস বা বৈশিষ্ট্যযুক্ত বস্তুগুলির রেফারেন্স এবং কাঁচা পয়েন্টারগুলিকে বোঝাতে ব্যবহৃত হয় । ফ্যাট পয়েন্টারে একটি পয়েন্টার এবং কিছু তথ্য থাকে যা ডিএসটিকে "সম্পূর্ণ" করে তোলে (যেমন দৈর্ঘ্য)।
মরিচায় সর্বাধিক ব্যবহৃত ধরণেরগুলি ডিএসটি নয় , তবে সংকলনের সময় একটি নির্দিষ্ট আকারের আকার রয়েছে। এই ধরণের বৈশিষ্ট্য প্রয়োগ করেSized
। এমনকি যে ধরণের গতিশীল আকারের হিপ বাফার পরিচালনা করে (যেমন Vec<T>
) Sized
এটি সংকলক হিসাবে Vec<T>
স্ট্যাকের উপর নির্ভরযোগ্য কোনও বাইটের সঠিক সংখ্যাটি জানে knows মরিচায় বর্তমানে চারটি বিভিন্ন ধরণের ডিএসটি রয়েছে।
স্লাইস ( [T]
এবং str
)
প্রকারটি [T]
(কারও জন্য T
) গতিশীল আকারের হয় (তেমনি বিশেষ "স্ট্রিং স্লাইস" প্রকার str
)। এজন্য আপনি সাধারণত এটিকে কেবল &[T]
বা হিসাবে হিসাবে দেখতে পান &mut [T]
, অর্থাত্ একটি রেফারেন্সের পিছনে। এই রেফারেন্সটি তথাকথিত "ফ্যাট পয়েন্টার"। আসুন পরীক্ষা করে দেখুন:
dbg!(size_of::<&u32>());
dbg!(size_of::<&[u32; 2]>());
dbg!(size_of::<&[u32]>());
এই মুদ্রণগুলি (কিছু পরিষ্কারের সাথে):
size_of::<&u32>() = 8
size_of::<&[u32; 2]>() = 8
size_of::<&[u32]>() = 16
সুতরাং আমরা দেখতে পাই যে একটি সাধারণ ধরণের মত একটি রেফারেন্স u32
8 বাইট বৃহত্তর, যেমন একটি অ্যারের রেফারেন্স [u32; 2]
। এই দুটি ধরণের ডিএসটি নয়। তবে [u32]
ডিএসটি হিসাবে এটির রেফারেন্স দ্বিগুণ is স্লাইসের ক্ষেত্রে, অতিরিক্ত তথ্য যা ডিএসটি "সম্পূর্ণ" করে দেয় তা কেবল দৈর্ঘ্য। সুতরাং কেউ বলতে পারে যে উপস্থাপনাটি &[u32]
হ'ল কিছু:
struct SliceRef {
ptr: *const u32,
len: usize,
}
বৈশিষ্ট্য অবজেক্টস ( dyn Trait
)
বৈশিষ্ট্যগুলিকে বৈশিষ্ট্যযুক্ত বস্তু হিসাবে ব্যবহার করার সময় (যেমন মুছে ফেলা, গতিশীলভাবে প্রেরণ করা), এই বৈশিষ্ট্যগুলি অবজেক্টগুলি ডিএসটি হয়। উদাহরণ:
trait Animal {
fn speak(&self);
}
struct Cat;
impl Animal for Cat {
fn speak(&self) {
println!("meow");
}
}
dbg!(size_of::<&Cat>());
dbg!(size_of::<&dyn Animal>());
এই মুদ্রণগুলি (কিছু পরিষ্কারের সাথে):
size_of::<&Cat>() = 8
size_of::<&dyn Animal>() = 16
আবার &Cat
মাত্র 8 বাইট বড় কারণ Cat
এটি একটি সাধারণ ধরণের। তবে dyn Animal
এটি একটি বৈশিষ্ট্যযুক্ত বস্তু এবং তাই গতিশীল আকারের। যেমন, &dyn Animal
16 বাইট বড়।
বৈশিষ্ট্যযুক্ত সামগ্রীর ক্ষেত্রে, অতিরিক্ত তথ্য যা ডিএসটি সম্পূর্ণ করে তা ভিটিবেলের (ভিটিপিআর) পয়েন্টার। আমি এখানে vtables এবং vptrs এর ধারণাটি পুরোপুরি ব্যাখ্যা করতে পারি না, তবে তারা এই ভার্চুয়াল প্রেরণের প্রসঙ্গে সঠিক পদ্ধতি বাস্তবায়নকে কল করতে ব্যবহৃত হয়। ভিটিবেল একটি স্ট্যাটিক টুকরা যা মূলত প্রতিটি পদ্ধতির জন্য একটি ফাংশন পয়েন্টার ধারণ করে। এটির সাথে, একটি বৈশিষ্ট্য অবজেক্টের একটি রেফারেন্স মূলত:
struct TraitObjectRef {
data_ptr: *const (),
vptr: *const (),
}
(এটি সি ++ থেকে আলাদা, যেখানে বিমূর্ত শ্রেণীর জন্য ভিটিপিআর বস্তুর মধ্যে সংরক্ষণ করা হয় Both উভয় পদ্ধতিরই সুবিধা এবং অসুবিধা রয়েছে))
কাস্টম ডিএসটি
শেষ ক্ষেত্রটি একটি ডিএসটি যেখানে স্ট্রাক্ট থাকার মাধ্যমে আপনার নিজের ডিএসটি তৈরি করা সম্ভব। এটি বরং বিরল, যদিও। এর একটি বিশিষ্ট উদাহরণ হ'ল std::path::Path
।
কাস্টম ডিএসটি-তে একটি রেফারেন্স বা পয়েন্টার হ'ল ফ্যাট পয়েন্টার। অতিরিক্ত তথ্য স্ট্রাক্টের ভিতরে কী ধরনের ডিএসটি থাকে তার উপর নির্ভর করে।
ব্যতিক্রম: বাহ্যিক প্রকারের
ইন বোঝায় যা RFC 1861 , extern type
বৈশিষ্ট্য চালু করা হয়। Extern ধরনের এছাড়াও DSTs, কিন্তু তাদের পয়েন্টার হয় না চর্বি পয়েন্টার। বা আরও ঠিক যেমনটি আরএফসি রাখে:
মরিচে, ডিএসটিগুলিতে পয়েন্টারগুলি বস্তুর দিকে নির্দেশিত হওয়ার বিষয়ে মেটাডেটা বহন করে। স্ট্রিং এবং টুকরোগুলির জন্য এটি বাফারের দৈর্ঘ্য, বৈশিষ্ট্যযুক্ত বস্তুর জন্য এটি অবজেক্টটির ভেটেবল। Extern ধরনের জন্য মেটাডাটা সহজভাবে হয় ()
। এর অর্থ বাহ্যিক ধরণের পয়েন্টারটির আকার একই usize
(যেমন, এটি "ফ্যাট পয়েন্টার" নয়)।
তবে আপনি যদি কোনও সি ইন্টারফেসের সাথে ইন্টারঅ্যাক্ট না করে থাকেন তবে সম্ভবত আপনাকে কখনই এই বাহ্যিক ধরণের সাথে ডিল করতে হবে না।
উপরে, আমরা পরিবর্তনীয় উল্লেখগুলির জন্য মাপগুলি দেখেছি। পরিবর্তনীয় রেফারেন্স, অপরিবর্তনীয় কাঁচা পয়েন্টার এবং পরিবর্তনীয় কাঁচা পয়েন্টারগুলির জন্য ফ্যাট পয়েন্টার একই কাজ করে:
size_of::<&[u32]>() = 16
size_of::<&mut [u32]>() = 16
size_of::<*const [u32]>() = 16
size_of::<*mut [u32]>() = 16