2016-09-06 12 views
7

मैं एक विशिष्ट प्रकार के बंद होने के लिए एक विशेषता को लागू करना चाहता हूं। यहाँ एक न्यूनतम उदाहरण (playground) है:बंद होने के लिए एक विशेषता को कार्यान्वित करने के परिणामस्वरूप बाध्य/ठोस जीवनकाल में विसंगति

trait Foo { 
    fn foo(&self, x: &u32); 
} 

impl<F> Foo for F 
    where F: Fn(&u32) 
{ 
    fn foo(&self, x: &u32) { 
     self(x) 
    } 
} 

fn main() { 
    let _: &FnOnce(&u32) = &|x| {}; // works 
    let _: &Foo   = &|x| {}; // doesn't work 
} 

यह इस त्रुटि में परिणाम है:

error: type mismatch resolving `for<'r> <[[email protected]<anon>:16:29: 16:35] as std::ops::FnOnce<(&'r u32,)>>::Output ==()`: 
expected bound lifetime parameter , 
    found concrete lifetime [--explain E0271] 
    --> <anon>:16:28 
    |> 
16 |>  let _: &Foo   = &|x| {}; 
    |>       ^^^^^^^ 
note: required because of the requirements on the impl of `Foo` for `[[email protected]<anon>:16:29: 16:35]` 
note: required for the cast to the object type `Foo` 

error: type mismatch: the type `[[email protected]<anon>:16:29: 16:35]` implements the trait `std::ops::Fn<(_,)>`, but the trait `for<'r> std::ops::Fn<(&'r u32,)>` is required (expected concrete lifetime, found bound lifetime parameter) [--explain E0281] 
    --> <anon>:16:28 
    |> 
16 |>  let _: &Foo   = &|x| {}; 
    |>       ^^^^^^^ 
note: required because of the requirements on the impl of `Foo` for `[[email protected]<anon>:16:29: 16:35]` 
note: required for the cast to the object type `Foo` 

मैं पहले से ही स्पष्ट रूप से where खंड इस तरह के HRTB जोड़ने की कोशिश की:

where F: for<'a> Fn(&'a u32) 

लेकिन इससे मदद नहीं मिली। मैं भी impl खंड पर जीवन भर के बजाय, इस तरह की घोषणा की:

impl<'a, F> Foo for F 
    where F: Fn(&'a u32) { ... } 

लेकिन इस impl ब्लॉक के भीतर एक जीवन भर त्रुटि का परिणाम है। I सोचें कि ये त्रुटियां सही हैं और impl ब्लॉक पर आजीवन पैरामीटर घोषित नहीं किया जा सकता है।

मैं इस उदाहरण को कैसे ठीक कर सकता हूं?

उत्तर

4

त्रुटि के इस हिस्से चेक आउट:

[...] implements the trait std::ops::Fn<(_,)> , but the trait for<'r> std::ops::Fn<(&'r u32,)> is required

मुझे लगता है कि वहाँ पर्याप्त कोड प्रकार समुचित रूप से अनुमान लगाया जा करने की अनुमति नहीं है कि मूल रूप से। एक स्पष्ट प्रकार एनोटेशन उदाहरण को जोड़ने से संकलित की:

let _: &Foo   = &|x: &u32| {}; 
+1

हम्म, तो संकलक इसका अनुमान क्यों नहीं लगा सकता? –

+0

@ChrisEmerson मुझे इसमें भी रूचि है! आपके और शेमपस्टर के जवाब ने पहले ही मेरी मदद की है! मेरे मामले में स्पष्ट प्रकार जोड़ना बहुत बुरा नहीं है और यह अब काम करता है। यह तय करना वास्तव में मुश्किल है कि कौन सा जवाब स्वीकार करना है: <... शायद वह जो समझा सकता है कि टाइप अनुमान क्यों विफल रहता है^_ ^ –

0

अस्वीकरण: मुझे नहीं पता कि मैं क्या कर रहा हूं।

निम्नलिखित काम करता है:

trait Foo<'a> { 
    fn foo(&self, x: &'a u32); 
} 

impl<'a, F> Foo<'a> for F where F: Fn(&'a u32) { 
    fn foo(&self, x: &'a u32) { 
     self(x) 
    } 
} 
+0

विशेषता का उपयोग करना (उदाहरण के लिए 'चलो एफ: और Foo = & | x | {}; f.foo (&3); ') इस समाधान के साथ असंभव हो जाता है। [खेल का मैदान] (https://play.rust-lang.org/ ? gist = 563c415937fa42d5311c7a08cdaae54f और संस्करण = स्थिर और बैकट्रैक = 0) –

+0

ठीक है, यह मेरे पावर स्तर से ऊपर है - बस सोचा कि आपने इस विकल्प को चेक नहीं किया होगा। – ljedrz

+0

हां, वैसे भी धन्यवाद :) –

3

यहाँ, एक आंशिक जवाब एक दिलचस्प प्रयोग के साथ शुरू:

trait Foo { 
    fn foo(&self, x: &u32); 
} 

impl<F> Foo for F 
    where F: Fn(&u32) 
{ 
    fn foo(&self, x: &u32) { 
     self(x) 
    } 
} 

fn main() { 
    let f1: &Fn(&u32) = &|_x| {}; 
    let f2: &Foo = &f1; 
    // but this fails: 
    // let f3: &Foo = &|_x| {}; 
    f2.foo(&3); 
} 

(Playground)

सभी मेरे द्वारा की गई है विशेषता के साथ FnOnceFn को गुण के साथ स्थिरता के लिए बदलें, और &Foo प्रकार के बाध्यकारी को अपना पहला बंद करें - और यह एक कार्य।

यह मुझे बताता है कि विशेषता स्वयं ठीक है - यह विशेषता वस्तु बनाते समय बंद होने के प्रकार का उल्लंघन करने में एक समस्या है। त्रुटि पर वापस जाकर, हमें बताया गया है कि बंद std::ops::Fn<(_,)> लागू करता है, लेकिन for<'r> std::ops::Fn<(&'r u32,)> आवश्यक है। इसका मतलब है कि आपने जिस चीज की कोशिश की थी (for<'r>... विशेषता के साथ जोड़ना) का कोई प्रभाव नहीं पड़ा क्योंकि विशेषता पहले से ही की आवश्यकता है।

इस बिंदु पर मैं फंस गया हूं - मुझे नहीं लगता कि मैं पर्याप्त विवरण में बंद होने के लिए अनुमान नियमों को समझता हूं या नहीं, यह देखने के लिए कि कोई अंतर क्यों है या इसे कैसे कामयाब है। मुझे आशा है कि कोई आएगा और इसे भर देगा!

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

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