2016-04-05 24 views
27

जंग के पास Any विशेषता है, लेकिन इसमें "आपके द्वारा उपयोग नहीं किए जाने वाले कार्यों के लिए भुगतान न करें" नीति भी है। जंग कैसे प्रतिबिंब लागू करता है?जंग कैसे प्रतिबिंब लागू करता है?

मेरा अनुमान है कि जंग आलसी टैगिंग का उपयोग करता है। प्रत्येक प्रकार को प्रारंभ में असाइन किया गया है, लेकिन बाद में यदि Any विशेषता की अपेक्षा रखने वाले फ़ंक्शन को टाइप किया गया है, तो इस प्रकार को TypeId असाइन किया गया है।

या शायद जंग प्रत्येक प्रकार पर TypeId डालता है कि इसका उदाहरण संभवतः उस कार्य को पारित किया गया है? मुझे लगता है कि पूर्व महंगा होगा।

उत्तर

37

सबसे पहले, जंग का प्रतिबिंब नहीं है; प्रतिबिंब का तात्पर्य है कि आप रनटाइम पर एक प्रकार के बारे में विवरण प्राप्त कर सकते हैं, जैसे फ़ील्ड्स, विधियों, इंटरफेस इसे लागू करते हैं, आदि आप जंग के साथ ऐसा नहीं कर सकते हैं। आप जो निकटतम प्राप्त कर सकते हैं वह स्पष्ट रूप से कार्यान्वित (या प्राप्त) एक विशेषता है जो इस जानकारी को प्रदान करता है।

प्रत्येक प्रकार को TypeId संकलित समय पर सौंपा जाता है। चूंकि वैश्विक रूप से आदेशित आईडी होने के कारण हार्ड है, आईडी प्रकार की परिभाषा के संयोजन से प्राप्त एक पूर्णांक है, और उस क्रेट के बारे में मिश्रित मेटाडेटा जिसमें यह निहित है। इसे एक और तरीका रखने के लिए: उन्हें किसी भी प्रकार के क्रम में असाइन नहीं किया गया है, वे टाइपिंग को परिभाषित करने वाली जानकारी के विभिन्न बिट्स के हैश हैं। [1]

आप source for the Any trait को देखें, तो आप Any के लिए एकल कार्यान्वयन देखेंगे:

impl<T: Reflect + 'static + ?Sized> Any for T { 
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() } 
} 

(सीमा हो सकता है अनौपचारिक कम करने के लिए "सभी प्रकार है कि से उधार नहीं कर रहे हैं कुछ और ")

तुम भी TypeId की परिभाषा पा सकते हैं:।

pub struct TypeId { 
    t: u64, 
} 

impl TypeId { 
    pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId { 
     TypeId { 
      t: unsafe { intrinsics::type_id::<T>() }, 
     } 
    } 
} 

intrinsics::type_id कंपाइलर द्वारा मान्यता प्राप्त एक आंतरिक कार्य है, जिसे एक प्रकार दिया जाता है, इसकी आंतरिक प्रकार आईडी लौटाता है। यह कॉल केवल शाब्दिक पूर्णांक प्रकार आईडी के साथ संकलन समय पर प्रतिस्थापित हो जाती है; वहां कोई वास्तविक यहां कॉल करें। [2] इस प्रकार TypeId जानता है कि एक प्रकार की आईडी क्या है। TypeId, फिर, उपयोगकर्ताओं से कार्यान्वयन विवरण छिपाने के लिए इस u64 के आस-पास एक आवरण है। यदि आपको यह अवधारणात्मक रूप से सरल लगता है, तो आप केवल एक प्रकार के TypeId को स्थिर 64-बिट पूर्णांक के रूप में सोच सकते हैं कि संकलक केवल संकलन समय पर जानता है। get_type_id से इस के लिए

Any आगे है, जिसका अर्थ get_type_idवास्तव में बस उपयुक्त TypeId::of विधि के लिए विशेषता विधि बाध्यकारी है। यह सुनिश्चित करने के लिए बस है कि यदि आपके पास Any है, तो आप मूल प्रकार के TypeId का पता लगा सकते हैं।

अब, Anyसबसे प्रकार के लिए लागू किया गया है, लेकिन इसका मतलब यह नहीं है उन सभी प्रकार वास्तव में है कि स्मृति में चारों ओर चल एक Any कार्यान्वयन।वास्तव में क्या होता है कि संकलक केवल कार्यान्वयन के लिए वास्तविक कोड उत्पन्न करता है यदि कोई कोड लिखता है जिसके लिए इसकी आवश्यकता होती है। [3] दूसरे शब्दों में, यदि आप किसी दिए गए प्रकार के लिए Any कार्यान्वयन का कभी भी उपयोग नहीं करते हैं, तो संकलक इसे कभी उत्पन्न नहीं करेगा।

इस प्रकार जंग ने "आप जो भी उपयोग नहीं करते हैं उसके लिए भुगतान न करें": यदि आप कभी भी &Any या Box<Any> के रूप में दिए गए प्रकार को पास नहीं करते हैं, तो संबंधित कोड कभी उत्पन्न नहीं होता है और कभी भी आपके संकलित बाइनरी में कोई स्थान नहीं लेता ।


[1]: Frustratingly, इसका मतलब है कि एक प्रकार का TypeId कर सकते हैं परिवर्तन मूल्य ठीक कैसे पुस्तकालय संकलित हो जाता है पर निर्भर करता है कि बात करने के लिए, एक निर्भरता के रूप में यह संकलन (के रूप में एक के रूप में करने का विरोध किया स्टैंडअलोन बिल्ड) TypeId एस बदलने के लिए कारण बनता है।

[2]: जैसा कि मुझे पता है के रूप में। I इस बारे में गलत हो सकता है, लेकिन मैं वास्तव में आश्चर्यचकित हूं कि यह मामला है।

[3]: यह आम तौर पर जंग में जेनेरिक के सच है।

+1

दिलचस्प बात यह है कि [std :: any के लिए प्रलेखन] (https://doc.rust-lang.org/std/any/) वाक्यांश "रनटाइम प्रतिबिंब" का उपयोग करता है, हालांकि ऐसा लगता है कि वे क्या संदर्भ दे रहे हैं यह नहीं है कि हम में से अधिकांश "रनटाइम प्रतिबिंब" से क्या मतलब है क्योंकि यह केवल मनमानी संरचना की सामग्री का निरीक्षण करने के बजाय प्रकार की जांच और प्रकार कास्टिंग सक्षम बनाता है। – Ixrec

+0

ठीक है। प्रतिबिंब से, मेरा मतलब आरटीटीआई है। –

+0

आप रनटाइम लागत के बिना विज्ञापन-हॉक प्रति प्रकार विशेष आवरण के सीमित रूपों के लिए 'AnyI 'के बिना' TypeId' का उपयोग कर सकते हैं। – bluss