2015-11-09 10 views
5

में पर्याप्त लंबे समय तक नहीं रहती है मुझे घोंसला वाले लैम्ब्डा के अंदर एक त्रुटि मिल रही है।परिवर्तनीय के साथ उधार-जांच त्रुटि नेस्टेड लैम्ब्डा

let rows = vec![ 
    vec![3, 6, 2, 8, 9, 0], 
    vec![0, 0, 1, 4, 5, 1], 
]; 

let pair_sums = rows.iter() 
    .flat_map(|row| { 
     (0..row.len() - 1).map(|i| row[i] + row[i + 1]) 
    }) 
    .collect::<Vec<_>>(); 

println!("{:?}", pair_sums); 
error[E0597]: `row` does not live long enough 
    --> src/main.rs:9:40 
    | 
9 |    (0..row.len() - 1).map(|i| row[i] + row[i + 1]) 
    |         --- ^^^ does not live long enough 
    |         | 
    |         capture occurs here 
10 |   }) 
    |   - borrowed value only lives until here 
11 |   .collect::<Vec<_>>(); 
    |       - borrowed value needs to live until here 

मैं इन सबसे छुटकारा देख सकते हैं क्यों यह हो रहा है, और मैं भीतरी लैम्ब्डा करने के लिए के माध्यम से row का मूल्य सूत्रण करके इसे ठीक कर सकते हैं:

let pair_sums = rows.iter() 
    .flat_map(|row| { 
     (0..row.len() - 1).zip(vec![row; row.len()]) 
      .map(|(i, row)| row[i] + row[i + 1]) 
    }) 
    .collect::<Vec<_>>(); 

यह भयानक है और यह कर सकते हैं ' टी सबसे अच्छा समाधान नहीं है। मैं स्पष्ट रूप से उन्हें पास किए बिना माता-पिता के दायरे में चर का संदर्भ कैसे दे सकता हूं?

उत्तर

7

यह चाल यह है कि बंदरगाह उनके चर को कैप्चर कैसे करते हैं: अगर उन्हें बंद करने की सामग्री द्वारा अनुमति दी जाती है, तो उन्हें बंद करने की सामग्री के द्वारा अनुमति दी जाती है, बिना अनुमान के स्थानीय को बंद करने की अभिव्यक्ति और अनुमानित रखने के लिए स्थानीय । इस मामले में row चर का उपयोग केवल संदर्भ द्वारा किया जाता है, इसलिए संदर्भ द्वारा कब्जा कर लिया जाना ठीक है; यानी, मानचित्र पर पास की गई बंद वस्तु row का संदर्भ है। इसलिए यह ऑब्जेक्ट उस स्कोप को नहीं छोड़ सकता है जो row वैरिएबल (यानी flat_map के बंद होने) की घोषणा करता है क्योंकि वह संदर्भ अमान्य स्मृति को इंगित करता है। .map(closure) लौटने से इस नियम का असफल हो जाएगा, क्योंकि .map एक आलसी इटरेटर बनाता है जो बंद करने को संग्रहीत करता है और केवल तत्वों के अनुरोध के रूप में इसे कॉल करता है।

यहां ठीक है row चर को संदर्भ द्वारा कैप्चर नहीं किया जाना है, ताकि बंद करने का दायरा छोड़ सके। यह move कीवर्ड के साथ किया जा सकता है:

let pair_sums = rows.iter() 
    .flat_map(|row| { 
     (0..row.len() - 1) 
      .map(move |i| row[i] + row[i + 1]) 
    }) 
    .collect::<Vec<_>>(); 

दूसरे शब्दों में, मूल कोड की तरह कुछ के बराबर है:

let pair_sums = rows.iter() 
    .flat_map(|row: &Vec<i32>| { 
     let row_ref: &&Vec<i32> = &row; 
     (0..row.len() - 1) 
      .map(move |i| (*row_ref)[i] + (*row_ref)[i + 1]) 
    }) 
    .collect::<Vec<_>>(); 

(मेरे Finding Closure in Rust पद और अधिक विस्तार से बंद में खोदता है, करता है Rust book।)

+0

धन्यवाद। मैंने कुछ महीनों के बाद इस जवाब को फिर से पढ़ा। वह हिस्सा जो स्पष्ट नहीं था आलसी नक्शा इटेटरेटर है। कनेक्टिंग-बाय-रेफरेंस के साथ कनेक्ट करने से यह सब समझ में आता है। –

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