diff --git "a/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/config.json" "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/config.json" index 74623cc48dd348ef0c2999e3a214745234eadd3d..3a4e07b643ba90b77c1f51c6cb5a8ef8c3adbc29 100644 --- "a/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/config.json" +++ "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/config.json" @@ -2,7 +2,9 @@ "node_id": "rust-4844e545058847c8b3198330fcedd12c", "keywords": [], "children": [], - "export": [], + "export": [ + "functional_programming.json" + ], "keywords_must": [], "keywords_forbid": [] } \ No newline at end of file diff --git "a/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.json" "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.json" new file mode 100644 index 0000000000000000000000000000000000000000..fa5bb2ac1a04f7df08879e83c5fd0696464ec22b --- /dev/null +++ "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.json" @@ -0,0 +1,7 @@ +{ + "type": "code_options", + "author": "jackymao_com", + "source": "functional_programming.md", + "notebook_enable": false, + "exercise_id": "" +} \ No newline at end of file diff --git "a/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.md" "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.md" new file mode 100644 index 0000000000000000000000000000000000000000..2339a4c4dcf05122fa097cb7c1f939e5dd954c90 --- /dev/null +++ "b/data/1.rust\345\210\235\351\230\266/2.rust\345\237\272\346\234\254\346\246\202\345\277\265/12.\345\207\275\346\225\260\345\274\217\347\274\226\347\250\213/functional_programming.md" @@ -0,0 +1,163 @@ +# 函数式编程 + +虽然 rust 语言主要是指令式编程,但也借鉴了很多函数式编程的精华,譬如 rust 中的迭代器、闭包、高阶函数等。 + +Rust 迭代器函数式编程主要用到的有: +- map +- for_each +- filter +- filter_map +- fold +- reduce +- zip +- collect + +用法如下: + +```rust + +#![allow(unused_variables)] +#![allow(dead_code)] + +use std::collections::HashMap; + +fn main() { + + let v: Vec<_> = (0..20).collect(); + // println!("{:?}", v); + + let values = vec![1, 2, 3, 4, 5].into_iter(); + let _sum = values.clone().reduce(|acc, x| acc + x); + // println!("{:?} {:?}", &values, _sum); + + let m = (1..5).fold(2, |mul, x| mul * x); + let n = (1..101).fold(0, |a, b| a + b); + // println!("{:?} {:?}", m, n); + + // fold is like reduce but can return an accumulator of a different type than the items of the iterator + let values = vec!["Hello", "World", "!"].into_iter(); + let _sentence = values.clone().fold(String::new(), |acc, x| acc + x); + // println!("{:?} {:?}", values, _sentence); + + let v = vec!["Hello", "World", "!"].into_iter(); + let w: Vec = v.clone().map(String::from).collect(); + // println!("{:?} {:?}", v, w); + + let even: Vec<_> = (0..10).filter(|x| x % 2 == 0).collect(); + // println!("{:?}", even); + + let v = vec![-1, 2, -3, 4, 5].into_iter(); + let _positive_numbers: Vec = v.clone() + .inspect(|x| println!("Before filter: {}", x)) + .filter(|x: &i32| x.is_positive()) + .inspect(|x| println!("After filter: {}", x)) + .collect(); + println!("{:?} {:?}", v, _positive_numbers); + + let v: Vec = [1, 2, 3].into_iter().map(|x| x + 1).rev().collect(); + assert_eq!(v, [4, 3, 2]); + + let names = vec!["Alice", "Bob", "Charlie"]; + let scores = vec!["90", "80", "95"]; + let score_map: HashMap<_, _> = names.iter() + .zip(scores.iter()) + .collect(); + println!("{:?} {:?} {:?}", names, scores, score_map); + + fn filter_map_test() { + let v = vec!["Hello", "World", "!"].into_iter(); + + let w: Vec = v.clone() + .filter_map(|x| { + if x.len() > 2 { + Some(String::from(x)) + } else { + None + } + }) + .collect(); + println!("{:?} {:?}", v, w); + + assert_eq!(w, vec!["Hello".to_string(), "World".to_string()]); + } + + filter_map_test(); + +} + +``` + +使用的时候如果编译出现错误,就要注意到有的函数是会消耗迭代器的元素,有的会返回一个迭代器,有的是惰性的。 + +下面的例子能正确编译的是: + +## 答案 + +```rust + +fn main() { + let arr = vec![0; 10]; + for i in arr.iter() { + println!("{:?}", i) + } + + println!("{:?}",arr); +} + +``` + +## 选项 + +### + +```rust + +fn main() { + let arr = vec![0; 10]; + for i in &arr.iter() { + println!("{:?}", i) + } + + println!("{:?}",arr); +} + +``` + +### + +```rust + +fn main() { + let arr = vec![0; 10]; + for i in arr { + println!("{:?}", i) + } + + println!("{:?}",arr); +} + +``` + +### + +```rust + +fn main() { + let arr = vec![0; 10]; + for i in arr.into_iter() { + println!("{:?}", i) + } + + println!("{:?}",arr); +} + +``` + + + \ No newline at end of file