2015-05-26 8 views
31

मैं एक प्रोग्राम लिखने की कोशिश कर रहा हूं जिसमें एरेज़ पर फ़िल्टरिंग और फोल्डिंग शामिल है। मैं संदर्भ के रूप में The Rust Programming Language, first edition का उपयोग कर रहा हूं, लेकिन मुझे समझ में नहीं आता कि जब मैं एरे पर इटरेटर बनाते हैं तो क्या होता है। यहाँ एक उदाहरण है:एक सरणी पर फिर से कैसे करें?

fn compiles() { 
    let range = (1..6); 
    let range_iter = range.into_iter(); 
    range_iter.filter(|&x| x == 2); 
} 

fn does_not_compile() { 
    let array = [1, 4, 3, 2, 2]; 
    let array_iter = array.into_iter(); 
    //13:34 error: the trait `core::cmp::PartialEq<_>` is not implemented for the type `&_` [E0277] 
    array_iter.filter(|&x| x == 2); 
} 

fn janky_workaround() { 
    let array = [1, 4, 3, 2, 2]; 
    let array_iter = array.into_iter(); 
    // Note the dereference in the lambda body 
    array_iter.filter(|&x| *x == 2); 
} 

(Rust playground)

पहले समारोह में, मैं पालन कि सीमा पर इटरेटर स्वामित्व नहीं ले करता है, तो मैं filter के लैम्ब्डा में एक &x ले लेना चाहिए, लेकिन मुझे समझ में नहीं आता कि सरणी के साथ दूसरा उदाहरण अलग-अलग व्यवहार क्यों करता है।

उत्तर

25

इस तरह के मामलों में, कंपाइलर को आपको चर के प्रकार के बारे में बताने के लिए मजबूर करना बहुत उपयोगी है।

array_iter.filter(|x| { let() = x; true }); 

इस के साथ विफल:: चलो एक असंगत प्रकार के बंद होने के तर्क सौंप कर आप प्रकार की त्रुटि को गति प्रदान करते हैं

error[E0308]: mismatched types 
    --> src/main.rs:12:33 
    | 
12 |  array_iter.filter(|x| { let() = x; true }); 
    |         ^^ expected &&{integer}, found() 
    | 
    = note: expected type `&&{integer}` 
       found type `()` 

अब हम जानते हैं कि x के प्रकार के एक &&{integer} है - के लिए एक संदर्भ के लिए एक संदर्भ कुछ पूर्णांक की तरह। इसके बाद हम इसके खिलाफ मैच कर सकते हैं:

fn hooray() { 
    let array = [1, 4, 3, 2, 2]; 
    let array_iter = array.into_iter(); 
    array_iter.filter(|&&x| x == 2); 
} 

प्रश्न अब "संदर्भ का संदर्भ क्यों है"? लघु संस्करण यह है कि iterator of an array returns references (type Item = &'a T भाग देखें)। इसके अलावा, Iterator::filter passes a reference को रोकने के लिए बंद करने के बाद और बाद में गैर-Copy प्रकार खोने के लिए बंद करें।

+1

धन्यवाद! मैंने यह जवाब चुना क्योंकि यह मुझे चला गया कि मैंने संकलक का इस्तेमाल अपने आप को समझने के लिए कैसे किया होगा। मैंने और जानने के लिए लिंक की भी सराहना की। – WillEngler

19

किसी भी तत्व प्रकार T और निरंतर संख्या N के लिए जंग में [T; N] प्रकार हैं। यह एक निश्चित आकार सरणी है।

जंग इस समय सरणी के लिए मूल्य-मानकों को लागू नहीं करता है। सभी सरणी स्लाइस के लिए वाणिज्य ([T] टाइप करें) और इस वजह से स्लाइस विधियों सरणी पर उपलब्ध हैं। सरणी को स्लाइस के इटरेटर भी मिलते हैं, जिसे std::slice::Iter<'a, T> कहा जाता है और इसमें &'a T के तत्व होते हैं: यह संदर्भ द्वारा पुनरावृत्त होता है!

यही कारण है कि into_iter() एक Range<i32> पर एक [i32; 5] पर i32 और into_iter() का एक इटरेटर का उत्पादन &i32 का एक इटरेटर उत्पादन होता है।

यदि आपको सरणी के लिए मूल्य इटरेटर की आवश्यकता है, तो उन्हें व्यापक पारिस्थितिक तंत्र में लागू किया गया है, (1) और (2) देखें।

0

रूप Shepmaster और bluss ने कहा, आप जांच कर सकते documentation for the array type, जो उल्लेख है:

आकार के

सरणी 0 से 32 (सम्मिलित) के लिए निम्न लक्षण को लागू करता है, तो तत्व प्रकार यह अनुमति देता है:

  • IntoIterator
( &[T; N] और &mut [T; N] के लिए लागू) 210

जैसा कि यह कहता है, यह केवल संदर्भों के लिए है, और Item प्रकार: type Item = &'a T और type Item = &'a mut T में दिखाई देता है।

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