2015-09-16 3 views
6

के लिए लागू नहीं किया गया है, मैं एक फ़ंक्शन बनाना चाहता हूं जो सूची को दो में विभाजित करता है: एक सूची जिसमें मूल सूची के तत्व शामिल होते हैं जो एक निश्चित भविष्य को पूरा करते हैं, और दूसरा जिसमें सभी नहीं होते हैं ।आकार का प्रकार एफएन

error[E0277]: the trait bound `for<'r> std::ops::Fn(&'r T) -> bool + 'static: std::marker::Sized` is not satisfied 
--> src/main.rs:1:47 
    | 
1 | fn split_filter<T: Clone + Sized>(a: &Vec<T>, f: Fn(&T) -> bool) -> (Vec<T>, Vec<T>) { 
    |            ^`for<'r> std::ops::Fn(&'r T) -> bool + 'static` does not have a constant size known at compile-time 
    | 
    = help: the trait `std::marker::Sized` is not implemented for `for<'r> std::ops::Fn(&'r T) -> bool + 'static` 
    = note: all local variables must have a statically known size 

error[E0308]: mismatched types 
    --> src/main.rs:17:39 
    | 
17 |  println!("{:?}", split_filter(&v, |&a| a % 3 == 0)); 
    |          ^^^^^^^^^^^^^^^ expected trait std::ops::Fn, found closure 
    | 
    = note: expected type `for<'r> std::ops::Fn(&'r {integer}) -> bool + 'static` 
       found type `[[email protected]/main.rs:17:39: 17:54]` 

दूसरा त्रुटि सूचित करते हैं कि एक बंद एक Fn नहीं है लगता है:

fn split_filter<T: Clone + Sized>(a: &Vec<T>, f: Fn(&T) -> bool) -> (Vec<T>, Vec<T>) { 
    let i: Vec<T> = vec![]; 
    let e: Vec<T> = vec![]; 
    for u in a.iter().cloned() { 
     if f(&u) { 
      i.push(u) 
     } else { 
      e.push(u) 
     } 
    } 

    return (i, e); 
} 

fn main() { 
    let v = vec![10, 40, 30, 20, 60, 50]; 
    println!("{:?}", split_filter(&v, |&a| a % 3 == 0)); 
} 

हालांकि, मैं दो त्रुटियों मिलती है: नीचे मेरी प्रयास है। मैंने सिंटैक्स f: |&T| -> bool का उपयोग करने की कोशिश की जिसे मैंने कहीं ऑनलाइन पाया, लेकिन यह जंग के नवीनतम संस्करण में काम नहीं कर रहा है।

पहली त्रुटि के लिए, मैंने आशा की थी कि TSized इसे बनाना होगा ताकि फ़ंक्शन का ज्ञात आकार हो, लेकिन स्पष्ट रूप से ऐसा नहीं होता है।

+3

भावी पाठकों के लिए, यह विधि पहले से ही ['partition'] (http://doc.rust-lang.org/std/iter/trait.Iterator.html#method.partition) नाम के तहत पुनरावृत्तियों के लिए लागू की गई है। । – Shepmaster

उत्तर

9

आपको आधिकारिक जंग पुस्तक, विशेष रूप से the chapter on closures पढ़ना चाहिए। आपका फ़ंक्शन घोषणा गलत है; आप निर्दिष्ट कर रहे हैं कि f में एक नंगे विशेषता प्रकार है, जो असंभव है; यह ठीक है कि Sized के बारे में त्रुटि क्या है। आप के बजाय एक सामान्य प्रकार पैरामीटर का उपयोग करना चाहिए:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>) 
where 
    F: for<'a> Fn(&'a T) -> bool, 

मैं भी &[T] को &Vec<T> से a का प्रकार बदल गए हैं; ऐसी कोई स्थिति नहीं है जिसमें आप बाद वाले को पसंद करेंगे। &Vec<T> स्वचालित रूप से आवश्यक होने पर &[T] पर ले जाया गया है। Why is it discouraged to accept a reference to a String (&String) or Vec (&Vec) as a function argument?

दूसरी त्रुटि फ़ंक्शन घोषणा में गलती से बारीकी से बंधी हुई है; आपके मूल कार्य घोषणा ने एक नंगे विशेषता प्रकार निर्दिष्ट किया है, लेकिन बंद होने के इस प्रकार नहीं हैं, वे केवल फ़ंक्शन विशेषता लागू करते हैं।

अंतिम कार्यक्रम इस प्रकार है:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>) 
where 
    F: Fn(&T) -> bool, 
{ 
    let mut i: Vec<T> = vec![]; 
    let mut e: Vec<T> = vec![]; 
    for u in a.iter().cloned() { 
     if f(&u) { 
      i.push(u); 
     } else { 
      e.push(u); 
     } 
    } 

    return (i, e); 
} 

fn main() { 
    let v = vec![10, 40, 30, 20, 60, 50]; 
    println!("{:?}", split_filter(&v, |&a| a % 3 == 0)); 
} 

playground पर यह कोशिश करो।

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