2015-09-14 5 views
11

के लिए AsRef या अन्य रूपांतरण लक्षणों का उपयोग कब करें, मैं जंग स्थिर (अब तक, संस्करण 1.2) में एक क्रेट एपीआई परिभाषित कर रहा हूं और अपने स्वयं के स्ट्रिंग-जैसे प्रकारों को परिभाषित करने के लिए सर्वोत्तम प्रथाओं के बारे में परेशान हूं।स्ट्रिंग-जैसे प्रकार

उदाहरण के लिए, मेरे पास Foo प्रकार है जो स्ट्रिंग को लपेटता है।

pub struct Foo(String); 

मेरे एपीआई Foo उदाहरणों के निर्माण को छुपाता है, और, इसके अलावा, क्योंकि टपल क्षेत्र निजी है, आवेदन गलती से खुद के लिए गलत Foo मूल्य का निर्माण नहीं कर सकते। इसका मतलब है कि मेरी एपीआई केवल वैध Foo मानों के साथ काम करने के लिए एप्लिकेशन को प्रतिबंधित करती है। अब तक सब ठीक है।

हालांकि, मैं आवेदन जैसे कि यह एक स्ट्रिंग-कहते है, उसे प्रिंट यह प्रवेश करने, एक फ़ाइल में लिखने के लिए, यह एक तीसरे पक्ष के टोकरे कि &str स्वीकार करता है को पास करते समय Foo उदाहरण उपयोग करने में सक्षम होना चाहता हूँ, to_string() के माध्यम से प्रतिलिपि बनाना और प्रतिलिपि बनाना आदि। संक्षेप में, मैं चाहता हूं कि एप्लिकेशन Foo -ness को अंतर्निहित स्ट्रिंग के संदर्भ के साथ "कास्ट" करने में सक्षम हो। चूंकि एप्लिकेशन कच्चे स्ट्रिंग को Foo उदाहरण में परिवर्तित नहीं कर सकता है, इसलिए टाइप-सुरक्षा संरक्षित है।

मेरा प्रश्न है: Foo के लिए मेरे क्रेट को कार्यान्वित करने के लिए Foo -ness को कच्चे स्ट्रिंग के रूप में अंतर्निहित स्ट्रिंग के साथ काम करने की अनुमति देने के लिए क्या करना चाहिए? यह महत्वपूर्ण है कि Foo&str में कनवर्ट करें ताकि अंतर्निहित स्ट्रिंग की किसी भी अनावश्यक प्रतिलिपि को कम किया जा सके।

उदाहरण के लिए, कैसे?

impl AsRef<str> for Foo 

क्या यह सही काम है? क्या यह मूर्खतापूर्ण होना पर्याप्त है? क्या कोई अन्य रूपांतरण लक्षण है जो मुझे Foo के लिए लागू करने पर विचार करना चाहिए?

उत्तर

8

तो एक Foo शब्दार्थ एक स्ट्रिंग है, तो Deref<Target = str> (या संभवतः Deref<Target = String> और DerefMut) को लागू करने करने के लिए मुख्य बात है। यही कारण है कि तरीकों कि str पर परिभाषित कर रहे हैं बुला, &Foo&str को मजबूर करने के लिए है, तो आप &*foo तरह बातें लिखना एक &str एक Foo से बाहर है, और foo.starts_with("bar") और इस तरह प्राप्त करने के लिए कर सकते हैं की अनुमति देगा।

कार्यान्वयन AsRef कुछ चीजों के लिए भी फायदेमंद होगा। Borrow एक और चीज है जिसे आप चाहते हैं, though there are things to consider before doing so

+1

आपका 'start_with' उदाहरण बहुत साफ हो जाता है। हालांकि, मैंने पुस्तक अनुभाग को 'असरफ' और 'उधार' के बारे में पढ़ा है-अभी भी स्पष्ट नहीं है। क्या 'AsRef'' और str 'में मजबूती के लिए अनुमति देता है लेकिन' start_with' उदाहरण के लिए अनुमति के बिना? कुछ मामलों क्या हैं जिन्हें मुझे 'डेफ' के बजाय 'AsRef' लागू करना चाहिए? क्या मुझे कभी दोनों को लागू करना चाहिए? –

+2

'डेफ्र' जादू है और एक प्रकार के लिए किया जा सकता है। 'AsRef' पूरी तरह गैर-जादू है और कई प्रकार के लिए किया जा सकता है। दोनों को लागू करना आम है। –

संबंधित मुद्दे