2015-06-04 12 views
8

मैं एक मल्टीक्टर से 2-आयामी मैट्रिक्स बनाने की कोशिश कर रहा हूं जो प्रत्येक तत्व बनाता है, और इसे एक फ्लैट वेक (प्रत्येक पंक्ति को संयोजित) के रूप में संग्रहीत करता है।नेस्टेड मानचित्र में बंद करने का उपयोग कैसे करें?

मैंने प्रत्येक पंक्ति बनाने और इसे संयोजित करने के लिए नेस्टेड मानचित्र (वास्तव में एक flat_map और एक नेस्टेड मानचित्र) का उपयोग किया। Here is what I tried:

fn make<T,F>(n: usize, m: usize, f: F) -> Vec<T> 
    where F: Fn(usize,usize) -> T 
{ 
    (0..m).flat_map(|y| (0..n).map(|x| f(x,y))).collect() 
} 

fn main() { 
    let v = make(5,5, |x,y| x+y); 

    println!("{:?}", v); 
} 

दुर्भाग्य से, मैं संकलन के दौरान कोई त्रुटि मिलती है (सामान्य 'काफी देर तक नहीं रहते')। नेस्टेड मानचित्रों में बंद करने का उपयोग कैसे किया जाता है?

<anon>:4:36: 4:46 error: `y` does not live long enough 
<anon>:4  (0..m).flat_map(|y| (0..n).map(|x| f(x,y))).collect() 
              ^~~~~~~~~~ 
<anon>:4:5: 4:58 note: reference must be valid for the method call at 4:4... 
<anon>:4  (0..m).flat_map(|y| (0..n).map(|x| f(x,y))).collect() 
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
<anon>:4:25: 4:47 note: ...but borrowed value is only valid for the scope of parameters for function at 4:24 
<anon>:4  (0..m).flat_map(|y| (0..n).map(|x| f(x,y))).collect() 
           ^~~~~~~~~~~~~~~~~~~~~~ 

(मैं इस मुद्दे by using a single map on 0..n*m के आसपास काम किया, लेकिन मैं अभी भी जवाब में दिलचस्पी रखता हूँ।)

+0

शायद http://stackoverflow.com/q/28521637/155423 का डुप्लिकेट? – Shepmaster

+0

मुझे आशा है कि y: usize कॉपी-सक्षम था, इसे आंतरिक बंद करके मूल्य से लिया जा सकता है, इस प्रकार किसी उधार लेने की आवश्यकता से परहेज किया जा सकता है ... – Gyscos

+0

मैं सहमत हूं, और मुझे आश्चर्य है कि यहां एक त्रुटि है सब - मुझे लगता है कि इसे 'FnMut' के साथ करना है। एक वास्तविक बग भी हो सकता है, क्योंकि सभी चरों पर '.clone()' छिड़कने से समस्या ठीक नहीं होती है क्योंकि मैंने सोचा था कि यह भी होगा। – Shepmaster

उत्तर

7

आपके मामले में आंतरिक बंद |x| f(x,y) एक उधार बंद है, जो अपने पर्यावरण (y और f लेता है) संदर्भ से।

.flat_map(..) काम करता है, यह आपको y का संदर्भ रखने के लिए मना करता है, जो बाहरी दायरे से नहीं है।

(0..m).flat_map(|y| (0..n).map(move |x| f(x,y))).collect() 

हालांकि, अब एक और समस्या पैदा होती है: इस प्रकार हम अपने बंद एक usize जो Copy है किया जा रहा है y के लिए मूल्य द्वारा अपने पर्यावरण, जो एक समस्या नहीं है लेने की आवश्यकता है

<anon>:5:41: 5:51 error: cannot move out of captured outer variable in an `FnMut` closure 
<anon>:5  (0..m).flat_map(|y| (0..n).map(move |x| f(x,y))).collect() 
               ^~~~~~~~~~ 

यहां, rustc खुश नहीं है: हम f को बंद करने के साथ-साथ बंद होने की कोशिश कर रहे हैं, जो निश्चित रूप से संभव नहीं है (जब तक m1 नहीं है, लेकिन संकलक इसे नहीं जानता)।

लेकिन f एक Fn(usize,usize) -> T, हम साथ ही स्पष्ट रूप से इसे करने के लिए एक & संदर्भ दे सकते हैं जिसका मतलब है कि है, और & संदर्भ Copy हैं:

fn make<T,F>(n: usize, m: usize, f: F) -> Vec<T> 
    where F: Fn(usize,usize) -> T 
{ 
    let f_ref = &f; 
    (0..m).flat_map(|y| (0..n).map(move |x| f_ref(x,y))).collect() 
} 

इस मामले में, बंद मूल्य द्वारा अपने पर्यावरण लेता है, और यह वातावरण y और f_ref से बना है, दोनों Copy हैं, सब कुछ ठीक है।

+2

आप "एफएन मेक (एन: यूजइज, एम: यूजइज, रेफ एफ: एफ) -> वीईसी " बंद करने के लिए संदर्भ लेने के लिए भी लिख सकते हैं। –

+0

बिल्कुल सही! मैं दूसरी त्रुटि से उलझन में आया, मुझे नहीं पता था कि यह एफ के बारे में बात कर रहा था ... @ एबी .: अच्छा! मैं फ़ंक्शन तर्कों में पैटर्न के बारे में भूल रहा हूं। – Gyscos

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