2016-08-24 14 views
6

मैं ऑनलाइन जंग के माध्यम से पढ़ रहा हूं और मैं 4.1, Operators and Overloading पर पहुंच गया हूं। मैंने देखा कि std::ops::Add इसे fn add(self, rhs: RHS) -> Self::Output; के रूप में परिभाषित करता है जिसमें type Output विशेषता में अलग से परिभाषित किया गया है।जंग के ऑपरेटरों के पास आउटपुट चर प्रकार क्यों है?

मैं समझता हूँ कि यहाँ क्या हो रहा है: add समारोह self के रूप में बाएं हाथ की ओर, और सामान्य पैरामीटर प्रकार RHS के रूप में दाहिने हाथ की ओर स्वीकार करता है।

मैं जानना चाहता हूं कि Output उपनाम के साथ आउटपुट प्रकार क्यों परिभाषित किया गया है, एक और सामान्य (उदा। Add<RHS, Output>) होने के बजाय? क्या यह सिर्फ एक सम्मेलन है, या इसके लिए कोई विशिष्ट कारण है?

उत्तर

7

जबकि कार्य चर पर काम करते हैं, तो आप गुणों के प्रकार के रूप में लक्षणों के बारे में सोच सकते हैं। इस तरह से सोचा जाने पर, प्रकार पैरामीटर फ़ंक्शन में इनपुट के रूप में कार्य करते हैं और संबंधित प्रकार आउटपुट के रूप में कार्य करते हैं।

Output के बाद से एक संबद्ध प्रकार, दो प्रकार के A और B कि हम impl Add करना चाहते हैं के लिए है, हम एक ही Output प्रकार उठा तक ही सीमित हैं। Output एक प्रकार पैरामीटर थे, हम impl AddA और B के असंख्य तरीके से कर सकते थे।

trait Mul<RHS, Output> { 
    fn mul(self, rhs: RHS) -> Output; 
} 

अब एक Complex प्रकार को परिभाषित करते हैं:

#[derive(Debug, Clone, Copy)] 
struct Complex { 
    x: f64, 
    y: f64, 
} 

impl Complex { 
    fn new(x: f64, y: f64) -> Complex { 
     Complex { x: x, y: y } 
    } 
} 

हम से गुणा करने के लिए सक्षम होना चाहते हैं

उदाहरण के लिए, हमें एक Mul विशेषता जहां Output एक पैरामीटर है निर्दिष्ट कर सकते हैं f64:

impl Mul<f64, Complex> for Complex { 
    fn mul(self, rhs: f64) -> Complex { 
     Complex::new(self.x * rhs, self.y * rhs) 
    } 
} 

यह सब ठीक काम करता है। हालांकि, हम एक दूसरे कार्यान्वयन के साथ आ सकता है:

impl Mul<f64, f64> for Complex { 
    fn mul(self, rhs: f64) -> f64 { 
     self.x * rhs 
    } 
} 

जब हम अब एक f64 द्वारा एक Complex गुणा, यह जो कार्यान्वयन बुलाया जाना चाहिए, और अतिरिक्त प्रकार की जानकारी फोन करने वाले द्वारा आपूर्ति किए जाने की जरूरत है अस्पष्ट है। Output एक संबंधित प्रकार बनाकर, यह अस्वीकृत है।निम्नलिखित कोड परस्पर विरोधी कार्यान्वयन के लिए एक संकलक त्रुटि फेंकता है:

impl std::ops::Mul<f64> for Complex { 
    type Output = Complex; 
    fn mul(self, rhs: f64) -> Complex { 
     Complex::new(self.x * rhs, self.y * rhs) 
    } 
} 

impl std::ops::Mul<f64> for Complex { 
    type Output = f64; 
    fn mul(self, rhs: f64) -> Complex { 
     self.x * rhs 
    } 
} 

Full example

+0

मैं देखता हूं। इसलिए, 'Mul ' के साथ, आपको यह निर्धारित करने के लिए कि आप किसकी आवश्यकता है, आपको अपने चर प्रकार को 'x: Complex' या 'x: f64' के रूप में सेट करने की आवश्यकता है, इसलिए' टाइप आउटपुट 'निर्णय मुख्य रूप से' स्वच्छता 'निर्णय था । यह सबसे अच्छा जवाब जैसा दिखता है लेकिन मैं यह सुनिश्चित करना चाहता हूं कि मैं इसे समझूं; क्या मैं पीछा करता हूँ? – BHustus

+0

इस तरह मैं इसे समझता हूं, हाँ। – paholg

+0

और इसी प्रकार, मानक कार्यान्वयन को 'ओवरराइट' करने के किसी भी प्रयास को विफलता से मुलाकात की जाएगी, जिसका अर्थ यह है कि किसी भी प्रकार के किसी भी प्रकार के 'टीडी' के लिए एक परिभाषित 'std :: ops :: Mul 'परिभाषित किया गया है, पर इसका भरोसा किया जा सकता है * केवल * कार्यान्वयन हो। ठीक है, मुझे लगता है कि मुझे यह मिल गया। धन्यवाद! – BHustus

4

यह है कि आउटपुट प्रकार निर्दिष्ट करने के लिए कौन है। आम तौर पर जब आप दो प्रकार गुणा करते हैं, तो f64f64 पर कहें, यह स्पष्ट है कि परिणाम का प्रकार क्या होना चाहिए: f64। कॉलर के परिणामके परिणाम प्रकार के लिए पूछने के लिए यह समझ में नहीं आता है - इसलिए यह वास्तव में इनपुट के रूप में समझ में नहीं आता है।

मैं कुछ मामलों की कल्पना कर सकता हूं जहां आप विकल्प अलग-अलग आउटपुट चाहते हैं, लेकिन वे थोड़ा सा आला हैं (u32 * u32 पूर्ण u64 परिणाम लौटाते हैं?); इसके अलावा यदि एक से अधिक विकल्प थे, तो आप यह निर्दिष्ट कैसे करते हैं कि आप कौन सा चाहते हैं? जबकि आप Add<u32, u64>::add(a, b) लिख सकते हैं, तो यह a*b*c संदिग्ध सरल अभिव्यक्ति करेगा और टाइप अनुमान को अधिक कठिन बना देगा!

+0

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

+1

'' जोड़ें 'आउटपुट' इनपुट प्रकार पैरामीटर बनाया जाएगा, लेकिन यह इनपुट नहीं है: यह एलएचएस (सेल्फ) और आरएचएस का एक कार्य है। मैं स्पष्ट होने के लिए अपने उत्तर को फिर से काम करने की कोशिश करूंगा। –

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