মরিচায় একটি "ফ্যাট পয়েন্টার" কী?


91

আমি ইতিমধ্যে বেশ কয়েকটি প্রসঙ্গে "ফ্যাট পয়েন্টার" শব্দটি পড়েছি, তবে আমি ঠিক জানি না এর অর্থ কী এবং কখন এটি জংতে ব্যবহৃত হয়। পয়েন্টারটি স্বাভাবিক পয়েন্টারের চেয়ে দ্বিগুণ বড় বলে মনে হয় তবে কেন তা বুঝতে পারছি না। বৈশিষ্ট্যযুক্ত বস্তুগুলির সাথে এটির কিছু আছে বলে মনে হয়।


7
শব্দটি নিজেই মরিচা-নির্দিষ্ট নয়, বিটিডাব্লু। ফ্যাট পয়েন্টারটি সাধারণত একটি পয়েন্টারকে বোঝায় যা কেবলমাত্র বস্তুর ঠিকানার দিকে নির্দেশ করা ছাড়াও কিছু অতিরিক্ত তথ্য সঞ্চয় করে stores যদি পয়েন্টারে কিছু ট্যাগ বিট থাকে এবং সেই ট্যাগ বিটের উপর নির্ভর করে পয়েন্টারটি কখনও কখনও বিন্দু হয় না তবে এটি ট্যাগ পয়েন্টার উপস্থাপনা বলে । (উদাহরণস্বরূপ অনেক স্মার্টলাক্স ভিএম-তে, পয়েন্টারগুলি 1 বিট দিয়ে শেষ হয় আসলে 31/63-বিট পূর্ণসংখ্যা হয়, যেহেতু পয়েন্টারগুলি শব্দ-সংযুক্ত থাকে এবং এভাবে 1 এ শেষ হয় না)) হটস্পট জেভিএম তার ফ্যাট পয়েন্টারগুলিকে ওওপিএস (অবজেক্ট-ওরিয়েন্টেড) বলে পয়েন্টার)।
জার্গ ডব্লু মিটাগ

4
কেবলমাত্র একটি পরামর্শ: যখন আমি প্রশ্নোত্তর জুটি পোস্ট করি তখন আমি সাধারণত একটি ছোট নোট লিখি যে এটি একটি স্ব-উত্তরযুক্ত প্রশ্ন, এবং কেন আমি এটি পোস্ট করার সিদ্ধান্ত নিয়েছি। প্রশ্নটির পাদটীকাটি এখানে দেখুন: stackoverflow.com/q/46147231/5768908
জেরার্ডো ফুর্তাদো

@ জেরার্ডোফুর্তাদো আমি প্রথমে এখানে একটি মন্তব্য পোস্ট করেছি যা ঠিক তা ব্যাখ্যা করে। তবে এটি এখন সরানো হয়েছিল (আমার দ্বারা নয়)। তবে হ্যাঁ, আমি একমত, প্রায়শই এই জাতীয় নোটটি কার্যকর!
লুকাস কালবার্টোড

উত্তর:


102

"ফ্যাট পয়েন্টার" শব্দটি গতিশীল আকারের ধরণের (ডিএসটি) - স্লাইস বা বৈশিষ্ট্যযুক্ত বস্তুগুলির রেফারেন্স এবং কাঁচা পয়েন্টারগুলিকে বোঝাতে ব্যবহৃত হয় । ফ্যাট পয়েন্টারে একটি পয়েন্টার এবং কিছু তথ্য থাকে যা ডিএসটিকে "সম্পূর্ণ" করে তোলে (যেমন দৈর্ঘ্য)।

মরিচায় সর্বাধিক ব্যবহৃত ধরণেরগুলি ডিএসটি নয় , তবে সংকলনের সময় একটি নির্দিষ্ট আকারের আকার রয়েছে। এই ধরণের বৈশিষ্ট্য প্রয়োগ করে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

সুতরাং আমরা দেখতে পাই যে একটি সাধারণ ধরণের মত একটি রেফারেন্স u328 বাইট বৃহত্তর, যেমন একটি অ্যারের রেফারেন্স [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 Animal16 বাইট বড়।

বৈশিষ্ট্যযুক্ত সামগ্রীর ক্ষেত্রে, অতিরিক্ত তথ্য যা ডিএসটি সম্পূর্ণ করে তা ভিটিবেলের (ভিটিপিআর) পয়েন্টার। আমি এখানে 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.