2015-01-17 8 views
18

मैंने दो तत्व Vector संरचना बनाई और मैं + ऑपरेटर को अधिभारित करना चाहता हूं।मैं संरचना के संदर्भ के लिए जोड़ें विशेषता कैसे कार्यान्वित करूं?

मैंने अपने सभी कार्यों और विधियों को मूल्यों के बजाय संदर्भ लेते हैं, और मैं + ऑपरेटर को उसी तरह काम करने के लिए चाहता हूं।

impl Add for Vector { 
    fn add(&self, other: &Vector) -> Vector { 
     Vector { 
      x: self.x + other.x, 
      y: self.y + other.y, 
     } 
    } 
} 

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

मैंने impl पर टेम्पलेट तर्कों के साथ-साथ Add पर उदाहरण देखे हैं, लेकिन वे केवल अलग-अलग त्रुटियों में परिणाम देते हैं।

मैं How can an operator be overloaded for different RHS types and return values? पाया, लेकिन जवाब में कोड काम नहीं करता है, भले ही मैं शीर्ष पर एक use std::ops::Mul; डाल दिया।

मैं rustc 1.0.0-रात का उपयोग कर रहा (ed530d7a3 2015-01-16 22:41:16 +0000)

मैं "के रूप में क्यों एक संदर्भ का उपयोग आप केवल दो फ़ील्ड हैं," को स्वीकार नहीं करेगा एक जवाब; अगर मैं 100 तत्व संरचना चाहता था तो क्या होगा? मैं एक ऐसा उत्तर स्वीकार करूंगा जो दर्शाता है कि एक बड़ी संरचना के साथ भी मुझे मूल्य से गुजरना चाहिए, अगर ऐसा है (मुझे नहीं लगता कि यह है, हालांकि।) मुझे संरचना आकार के लिए अंगूठे का अच्छा नियम जानने में दिलचस्पी है और मूल्य बनाम संरचना से गुजर रहा है, लेकिन यह वर्तमान सवाल नहीं है।

+0

"क्या होगा यदि मैं 100 तत्व संरचना चाहता हूं" - जंग आरवीओ जैसे अनुकूलन का उपयोग करता है जो उपयुक्त और बेहतर विकल्प के दौरान स्वचालित रूप से संदर्भ का उपयोग करेगा। – Shepmaster

+0

@ शेमपस्टर: आरवीओ केवल वापसी मूल्य को प्रभावित करने जा रहा है, जिसे मैं मूल्य से वापस कर रहा हूं। क्या आप किसी भी दस्तावेज को इंगित कर सकते हैं जो दिखाता है कि बड़े structs के लिए गुण मूल्य द्वारा लागू किया जाना चाहिए? –

+1

मुझे पता है कि सबसे अच्छा दस्तावेज [रिटर्निंग पॉइंटर्स पर पुस्तक अध्याय] होगा (http://doc.rust-lang.org/book/pointers.html#returning-pointers)। हालांकि, मैंने [एक बड़ी संरचना जोड़ने का एक उदाहरण बनाया] (http://is.gd/25ITa7) और जेनरेट किए गए एलएलवीएम (थोड़ा साफ) की जांच की: '(% struct.big * sret,% struct.big *,% struct.Big *) '। मैं एक एलएलवीएम विशेषज्ञ होने का दावा नहीं करता हूं, लेकिन ऐसा लगता है कि यह संदर्भ रूप से स्वचालित रूप से ले रहा है और लौट रहा है। – Shepmaster

उत्तर

28

आपको पर &Vector पर Add लागू करने की आवश्यकता है।

impl<'a, 'b> Add<&'b Vector> for &'a Vector { 
    type Output = Vector; 

    fn add(self, other: &'b Vector) -> Vector { 
     Vector { 
      x: self.x + other.x, 
      y: self.y + other.y, 
     } 
    } 
} 

इसकी परिभाषा में, Add::add हमेशा मूल्य द्वारा self लेता है। लेकिन संदर्भ किसी अन्य जैसे प्रकार हैं, इसलिए वे लक्षण भी कार्यान्वित कर सकते हैं। जब किसी संदर्भ प्रकार पर एक विशेषता लागू की जाती है, तो self का प्रकार एक संदर्भ है; संदर्भ मूल्य से पारित किया जाता है। आम तौर पर, जंग में मूल्य से गुजरने से संकेत मिलता है कि स्वामित्व स्थानांतरित हो जाता है, लेकिन जब संदर्भ मूल्य से पारित होते हैं, तो उन्हें आसानी से प्रतिलिपि बनाई जाती है (या यदि यह एक उत्परिवर्तनीय संदर्भ है तो इसे पुनर्स्थापित/स्थानांतरित किया जाता है), और यह संदर्भ के स्वामित्व को स्थानांतरित नहीं करता है (क्योंकि संदर्भ पहली जगह में इसके संदर्भ का मालिक नहीं है)। यह सब ध्यान में रखते हुए, (और कई अन्य ऑपरेटरों) को self मानने के लिए यह समझ में आता है: यदि आपको ऑपरेटरों का स्वामित्व लेने की आवश्यकता है, तो आप सीधे structs/enums पर Add लागू कर सकते हैं, और यदि आप नहीं करते हैं, तो आप कर सकते हैं संदर्भों पर Add लागू करें।

यहां, self प्रकार &'a Vector है, क्योंकि इस प्रकार हम Add पर लागू कर रहे हैं।

ध्यान दें कि मैंने इस तथ्य पर जोर देने के लिए RHS प्रकार पैरामीटर भी निर्दिष्ट किया है कि दो इनपुट पैरामीटर के जीवनकाल असंबंधित हैं।


वास्तव में, संदर्भ प्रकार है कि में विशेष अगर आप T के लिए एक विशेषता को लागू करने की अनुमति हो तो आप अपने टोकरा (यानी में प्रकार परिभाषित करने के संदर्भ के लिए लक्षण लागू कर सकते हैं, तो आप भी अनुमति हो &T के लिए इसे लागू करने के लिए)। &mut T और Box<T> समान व्यवहार करते हैं, लेकिन यह सामान्यतः U<T> के लिए सच नहीं है जहां U एक ही क्रेट में परिभाषित नहीं किया गया है।

+3

"जोड़ें :: जोड़ें हमेशा मूल्य से स्वयं लेता है। यहां, स्वयं प्रकार और 'वेक्टर है, क्योंकि वह प्रकार है जिसे हम कार्यान्वित कर रहे हैं। "यह महत्वपूर्ण जानकारी है, कि संदर्भ के संदर्भ में विशेषता के आधार पर स्वयं का प्रकार बदलता है या नहीं। धन्यवाद! –

+2

वाह। कि यह सही जवाब है, और फिर भी यह है। यह सब काफी उलझन में महसूस करता है। अगर आप संदर्भ के आधार पर दो अलग-अलग तरीकों से जोड़ सकते हैं या परेशानी के लिए नुस्खा की तरह महसूस नहीं करते हैं। – Squirrel

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