वहाँ जंग में downcasting करने के लिए दो तरीके हैं। पहला Any
का उपयोग करना है। ध्यान दें कि यह केवल आपको सटीक, मूल ठोस प्रकार पर डाउनकास्ट करने की अनुमति देता है। इसलिए जैसा:
use std::any::Any;
trait A {
fn as_any(&self) -> &Any;
}
struct B;
impl A for B {
fn as_any(&self) -> &Any {
self
}
}
fn main() {
let a: Box<A> = Box::new(B);
// The indirection through `as_any` is because using `downcast_ref`
// on `Box<A>` *directly* only lets us downcast back to `&A` again.
// The method ensures we get an `Any` vtable that lets us downcast
// back to the original, concrete type.
let b: &B = match a.as_any().downcast_ref::<B>() {
Some(b) => b,
None => panic!("&a isn't a B!")
};
}
दूसरी तरह के आधार विशेषता पर प्रत्येक 'लक्ष्य' के लिए एक विधि को लागू करने (इस मामले, A
में), और प्रत्येक वांछित लक्ष्य प्रकार के लिए डाले लागू है।
प्रतीक्षा, हम क्यों as_any
की ज़रूरत है?
भले ही आप A
के लिए आवश्यकता के रूप में जोड़ते हैं, फिर भी यह सही तरीके से काम नहीं करेगा। पहली समस्या यह है कि A
Box<A>
में भी लागू Any
... जिसका अर्थ है कि जब आप downcast_ref
पर कॉल करते हैं, तो आप वास्तव में इसे ऑब्जेक्ट प्रकार A
पर कॉल करेंगे। Any
केवल उस प्रकार के डाउनकास्ट को डाउनकास्ट किया जा सकता है, जिस पर इस मामले में A
है, इसलिए आप केवल &A
पर वापस आ सकते हैं जो आपके पास पहले से था।
लेकिन के अंतर्निहित प्रकार के लिए कहीं पर कार्यान्वयन है, है ना? खैर, हाँ, लेकिन आप इसे प्राप्त नहीं कर सकते हैं। जंग आपको &A
से &Any
से "कास्ट क्रॉस" करने की अनुमति नहीं देती है।
क्या as_any
है; क्योंकि यह केवल हमारे "कंक्रीट" प्रकारों पर लागू होता है, इसलिए संकलक भ्रमित नहीं होता है कि इसे किसके लिए बुलाया जाना चाहिए। इसे &A
पर कॉल करने से यह ठोस कार्यान्वयन (फिर से, इस मामले में, B::as_any
) को गतिशील रूप से प्रेषित करने का कारण बनता है, जो के Any
के कार्यान्वयन का उपयोग करके देता है, जो हम चाहते हैं।
ध्यान दें कि आप कर सकते हैं ओर कदम बस सभी पर A
का उपयोग नहीं द्वारा इस पूरे समस्या। विशेष रूप से, निम्नलिखित होगा भी काम:
fn main() {
let a: Box<Any> = Box::new(B);
let _: &B = match a.downcast_ref::<B>() {
Some(b) => b,
None => panic!("&a isn't a B!")
};
}
बहरहाल, यह किसी भी अन्य तरीकों होने से आप precludes; सभी आप यहां एक ठोस प्रकार के लिए डाउनकास्ट कर सकते हैं।
संभावित रुचि के अंतिम नोट के रूप में, mopa क्रेट आपको अपने खुद के गुण के साथ Any
की कार्यक्षमता को जोड़ने की अनुमति देता है।
हाँ:
यह बहुत ही इसी तरह के प्रश्न में बेहतर विकल्प है! मुझे लगता है कि यह मुझे फिट बैठता है। बहुत बहुत धन्यवाद। – Aleksandr
मैं पहली बार बात कर रहा हूं :) – Aleksandr
यह इंगित करने लायक है कि 'as_any' फ़ंक्शन की आवश्यकता क्यों है। यह 'बी' के लिए लागू किया गया है और 'B' प्रकार का पैरामीटर 'स्वयं' लेता है, जिसे 'और किसी भी' में परिवर्तित किया जाता है और बाद में इसे '& B' पर वापस लाया जा सकता है। 'A.as_any()' को '(& * ए और ए के साथ) के साथ प्रतिस्थापित किया जा सकता है, इसे केवल' और किसी भी 'में परिवर्तित प्रकार पर वापस लाया जा सकता है, जो 'और ए' है। 'और ए' और' & B' एक ही चीज़ नहीं हैं क्योंकि उनके पास भिन्न v-table हैं। – dhardy