2016-09-09 2 views
10

इस कोड (playground):अप्रत्याशित संकलक त्रुटि में एक विशेषता परिणाम पाने, लेकिन मैनुअल कार्यान्वयन काम करता है

#[derive(Clone)] 
struct Foo<'a, T: 'a> { 
    t: &'a T, 
} 

fn bar<'a, T>(foo: Foo<'a, T>) { 
    foo.clone(); 
} 

... संकलन नहीं है कुछ भी, जैसा कि यह पहले से ही प्रस्ताव में है।

जब मैं #[derive(Clone)] और मैन्युअल रूप से हटाने के लिए FooClone लागू, अपेक्षा के अनुरूप यह कम्पाइल हो गया!

impl<'a, T> Clone for Foo<'a, T> { 
    fn clone(&self) -> Self { 
     Foo { 
      t: self.t, 
     } 
    } 
} 

यहां क्या हो रहा है?

  • क्या #[derive()] -impls और मैन्युअल के बीच कोई अंतर है?
  • क्या यह एक कंपाइलर बग है?
  • कुछ और मैंने नहीं सोचा था?

उत्तर

20

जवाब त्रुटि संदेश में दफनाया गया है:

विधि clone मौजूद है, लेकिन निम्नलिखित विशेषता सीमा संतुष्ट नहीं थे: T : std::clone::Clone

जब आप प्राप्त Clone (और कई अन्य स्वचालित रूप से - प्रकार के प्रकार), यह Cloneपर सभी जेनेरिक प्रकारों को जोड़ता है। rustc -Z unstable-options --pretty=expanded का उपयोग करना, हम देख सकते हैं कि यह क्या हो जाता है:

impl <'a, T: ::std::clone::Clone + 'a> ::std::clone::Clone for Foo<'a, T> { 
    #[inline] 
    fn clone(&self) -> Foo<'a, T> { 
     match *self { 
      Foo { t: ref __self_0_0 } => 
      Foo{t: ::std::clone::Clone::clone(&(*__self_0_0)),}, 
     } 
    } 
} 

में इस मामले, बाध्य की जरूरत नहीं है क्योंकि सामान्य प्रकार एक संदर्भ के पीछे है।

अभी के लिए, आपको Clone स्वयं को लागू करने की आवश्यकता होगी। There's a Rust issue for this, लेकिन यह एक कामकाज के साथ तुलनात्मक रूप से दुर्लभ मामला है।

3

आपका उदाहरण बिना किसी समस्या के Clone प्राप्त होगा यदि आप स्पष्ट रूप से, निशान इस तरह कि TClone को लागू करना चाहिए:

#[derive(Clone)] 
struct Foo<'a, T: 'a> { 
    t: &'a T, 
} 

fn bar<'a, T: Clone>(foo: Foo<'a, T>) { 
    foo.clone(); 
} 

(Playground link)

ऐसा नहीं है कि आप स्पष्ट रूप से बाध्य निर्दिष्ट करने से बच सकते हैं असामान्य लगता है , लेकिन शेमपास्टर का जवाब यह सुझाव देता है कि संकलक इसे स्पष्ट रूप से सम्मिलित करता है, इसलिए मेरा सुझाव कार्यात्मक रूप से समान है।

+0

यह एक अच्छा समाधान है, लेकिन मैं * कार्यात्मक रूप से समान * से असहमत हूं - इस मामले में, संरचना में केवल 'टी' हो सकता है जो 'क्लोन' लागू करता है, लेकिन वह विशेष बाध्य ** आवश्यक ** नहीं है एक संदर्भ क्लोन करें। यदि कार्यक्रम को अन्य कारणों से 'टी' क्लोन करने की आवश्यकता है, तो यह काम करता है। – Shepmaster

+0

ओह, मुझे लगता है कि आपके उदाहरण से 'टी: :: std :: क्लोन :: क्लोन + 'ए' का मतलब है कि' टी' ने 'क्लोन' को लागू किया है; क्या मैं गलतफहमी कर रहा हूँ? – Aurora0001

+0

@ शेमपस्टर, कुछ परीक्षणों के बाद मुझे पता चला है कि आप बिना किसी समस्या के संरचना में 'टी' पर 'क्लोन' को बाध्य कर सकते हैं, और ऐसा करके मैं विस्तारित सुंदर प्रिंटर से मैन्युअल रूप से ' '। – Aurora0001

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