2015-11-19 5 views
9

से संग्रह भरते समय मिस्चैच "बाउंड आजीवन पैरामीटर" बनाम "ठोस जीवनकाल" टाइप करें, मैं एक पुनरावृत्ति अनुक्रम में दोहराव खोजने की कोशिश कर रहा हूं। इसके अलावा, मैं उस बिंदु पर उस अनुक्रम में हुए तत्वों को जानना चाहता हूं।बंद करें

मैंने HashMap बनाया और take_while द्वारा उपयोग किए गए बंद होने के भीतर insert पर कॉल करने का प्रयास कर रहा हूं। हालांकि, मैंने अब तक कंक्रीट/बाध्य जीवनकाल से संबंधित प्रकार के विसंगतियों के कारण संकलन करने में कामयाब नहीं रहा है।

use std::collections::HashSet; 

fn main() { 
    let mut seq = HashSet::new(); 
    let mut insert = |k| seq.insert(k); 
    (1..10).cycle().take_while(insert); 
} 

यहाँ त्रुटियों मैं कर रहे हैं::

error[E0631]: type mismatch in closure arguments 
--> src/main.rs:6:21 
    | 
5 |  let mut insert = |k| seq.insert(k); 
    |      ----------------- found signature of `fn(_) -> _` 
6 |  (1..10).cycle().take_while(insert); 
    |      ^^^^^^^^^^ expected signature of `for<'r> fn(&'r {integer}) -> _` 

error[E0271]: type mismatch resolving `for<'r> <[[email protected]/main.rs:5:22: 5:39 seq:_] as std::ops::FnOnce<(&'r {integer},)>>::Output == bool` 
--> src/main.rs:6:21 
    | 
6 |  (1..10).cycle().take_while(insert); 
    |      ^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime 

मैं कैसे करने के लिए इसके लिए कोड को बदलने की जरूरत है

यहाँ जो एक ही त्रुटि दर्शाती है मेरी कोड का एक सरलीकृत संस्करण है काम?

+0

उत्सुक है, यह अगर बंद 'take_while' कॉल में सीधे ले जाया जाता है काम करता है: http://is.gd/OgVK2i –

+0

@ker, यह काम करता है, क्योंकि आप एक बड़ी चालाकी से अलग बात कर रहे हैं - आप पैटर्न में एक अंतर्निहित dereference का उपयोग कर रहे हैं, जो मूल कोड नहीं है। –

उत्तर

8

वास्तव में यह छिपाने में उधार त्रुटि है।

Iterator<Item = T>::take_while()FnMut(&T) -> bool की तरह बंद करने को स्वीकार करता है - यानी, यह प्रत्येक तत्व को संदर्भ द्वारा बंद करने के लिए पास करता है। यह बहुत स्वाभाविक है क्योंकि take_while() सफलतापूर्वक परीक्षण तत्व उत्पन्न करने में सक्षम होना चाहिए, इसलिए यह इसे मूल्य से पारित नहीं कर सकता है।

इसका मतलब है कि insert तर्क प्रकार &_ होने के लिए मान लिया जाता है, और इसलिए HashSet के सामान्य पैरामीटर भी &_ के रूप में मान लिया जाता है। हालांकि, इसका मतलब यह है कि आप cycle() इटेटर द्वारा उत्पन्न संरचना के लिए अस्थायी मूल्यों के संदर्भों को संग्रहीत करने का प्रयास कर रहे हैं जो लंबे समय तक रहता है। उधार नियमों द्वारा इसकी अनुमति नहीं है। दुर्भाग्यवश, जंग बिल्कुल इस तर्क को नहीं दिखाती है क्योंकि किसी कारण से यह अनुमान नहीं लगा सकता कि संख्यात्मक प्रकार i32 है और यह बंद होने के लिए सही जीवनकाल पैरामीटर का अनुमान नहीं लगा सकता है। यही आपकी त्रुटि के बारे में है।

इसके बजाय, आपके बंद को सेट पर संग्रहीत करने से पहले तर्क को अव्यवस्थित करना चाहिए। This works:

use std::collections::HashSet; 

fn main() { 
    let mut seq = HashSet::new(); 
    let mut insert = |&k: &i32| seq.insert(k); 
    (1..10).cycle().take_while(insert); 
} 

मैं भी तर्क से भरा प्रकार जोड़ने के लिए किया था; जैसा कि मैंने उपरोक्त कहा है, मुझे लगता है कि प्रकार अनुमान इसे कम करने के लिए पर्याप्त शक्तिशाली नहीं है।

Btw, आप वास्तव में यदि आप प्रकार स्पष्ट रूप से निर्दिष्ट उधार चेकर त्रुटि प्राप्त कर सकते हैं:

use std::collections::HashSet; 

fn main() { 
    let mut seq = HashSet::new(); 
    let mut insert = |k: &i32| seq.insert(k); // no dereference 
    (1..10).cycle().take_while(insert); 
} 

ऊपर कोड स्पष्ट प्रकार एनोटेशन के लिए छोड़कर अपने मूल उदाहरण के बराबर है, और यह निम्नलिखित में परिणाम त्रुटि:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements 
--> src/main.rs:5:43 
    | 
5 |  let mut insert = |k: &i32| seq.insert(k); 
    |           ^
    | 
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 5:22... 
--> src/main.rs:5:22 
    | 
5 |  let mut insert = |k: &i32| seq.insert(k); 
    |      ^^^^^^^^^^^^^^^^^^^^^^^ 
note: ...so that expression is assignable (expected &i32, found &i32) 
--> src/main.rs:5:43 
    | 
5 |  let mut insert = |k: &i32| seq.insert(k); 
    |           ^
note: but, the lifetime must be valid for the block suffix following statement 1 at 5:5... 
--> src/main.rs:5:5 
    | 
5 |/ let mut insert = |k: &i32| seq.insert(k); 
6 | |  (1..10).cycle().take_while(insert); 
7 | | } 
    | |_^ 
note: ...so that variable is valid at time of its declaration 
--> src/main.rs:5:9 
    | 
5 |  let mut insert = |k: &i32| seq.insert(k); 
    |   ^^^^^^^^^^ 
+2

"मुझे तर्क का पूरा प्रकार भी जोड़ना पड़ा, जैसा कि मैंने ऊपर कहा था, मुझे लगता है कि टाइप अनुमान इसे कम करने के लिए पर्याप्त शक्तिशाली नहीं है।" मैं कुछ बार इस तरह की त्रुटियों में भाग गया। यह हमेशा बाध्यकारी में बंद होने के साथ है। ऐसा लगता है कि उन्हें तत्काल कैसे किया जाता है।एक संदर्भ होने के लिए पैरामीटर के प्रकार को निर्दिष्ट नहीं करते हैं, जिसके परिणामस्वरूप अनुमानित संदर्भ बंद होने के दायरे के जीवनकाल के साथ प्रारंभिक रूप से बाध्य होता है, जबकि अपेक्षित उच्च प्रकार के जीवनकाल के साथ एक संदर्भ में संदर्भ परिणाम निर्दिष्ट करते हैं। –

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