提交 de952b23 编写于 作者: 梦境迷离's avatar 梦境迷离

add rust function closures

上级 c2bf124e
///闭包
//by reference: &T 默认
//by mutable reference: &mut T
//by value: T
pub fn closures() {
//闭包是lambda,一个表达式可以省略大括号
fn function(i: i32) -> i32 { i + 1 }
let closure_annotated = |i: i32| -> i32 { i + 1 };
let closure_inferred = |i| i + 1;
let i = 1;
println!("function: {}", function(i));
println!("closure_annotated: {}", closure_annotated(i));
println!("closure_inferred: {}", closure_inferred(i));
let one = || 1;
println!("closure returning one: {}", one());
capturing();
let haystack = vec![1, 2, 3];
let contains = move |needle| haystack.contains(needle);
println!("{}", contains(&1));
println!("{}", contains(&4));
//println!("There're {} elements in vec", haystack.len());
input_parameters();
type_anonymity();
input_functions();
output_parameters();
closures_std();
higher_order_functions();
diverging_functions();
}
fn capturing() {
use std::mem;
let color = "green";
let print = || println!("`color`: {}", color);
print();
let _reborrow = &color;//闭包使用的color能被继续借用
print();//直到最后一次使用print
let _color_moved = color;//最后使用`print`后允许移动或重新借用
let mut count = 0;
let mut inc = || {
count += 1;
println!("`count`: {}", count);
};
inc();
//let _reborrow = &count;//已经被作为可变的借用出去,不可再借用给不可变的
inc();
let _count_reborrowed = &mut count;
//非copy的,被移动进闭包
let movable = Box::new(3);
let consume = || {
println!("`movable`: {:?}", movable);
mem::drop(movable);
};
consume();//仅能被使用一次。
}
fn input_parameters() {
//以闭包作为参数并调用它的函数。
fn apply<F>(f: F) where
// The closure takes no input and returns nothing.
F: FnOnce() {//按值捕获
// ^ TODO: Try changing this to `Fn` or `FnMut`.
f();
}
// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where F: Fn(i32) -> i32 {
f(3)
}
use std::mem;
let greeting = "hello";
//从借来的引用创建自己拥有的数据
let mut farewell = "goodbye".to_owned();
let diary = || {
println!("I said {}.", greeting);//捕获引用
farewell.push_str("!!!");//捕获可变引用
println!("Then I screamed {}.", farewell);
println!("Now I can sleep. zzzzz");
mem::drop(farewell);//捕获值
};
apply(diary);
let double = |x| 2 * x;
println!("3 doubled: {}", apply_to_3(double));
}
fn type_anonymity() {
// `F`必须是泛型的
fn apply<F>(f: F) where
F: FnOnce() {
f();
}
}
fn input_functions() {
//无返回值的
fn call_me<F: Fn()>(f: F) {
f();
}
fn function() {
println!("I'm a function!");
}
//满足Fn的闭包
let closure = || println!("I'm a closure!");
call_me(closure);
call_me(function);
}
fn output_parameters() {
fn create_fn() -> impl Fn() {
//必须使用move关键字,强制按值捕获避免函数退出时通过引用捕获的被丢弃而留下无效引用
let text = "Fn".to_owned();
move || println!("This is a: {}", text)
}
fn create_fnmut() -> impl FnMut() {
let text = "FnMut".to_owned();
move || println!("This is a: {}", text)
}
fn create_fnonce() -> impl FnOnce() {
let text = "FnOnce".to_owned();
move || println!("This is a: {}", text)
}
let fn_plain = create_fn();
let mut fn_mut = create_fnmut();
let fn_once = create_fnonce();
fn_plain();
fn_mut();
fn_once();
}
///https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find
fn closures_std() {
//any
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
println!("2 in vec1: {}", vec1.iter().any(|&x| x == 2));//不消耗集合,使用引用捕获
println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2));//消耗集合,使用值捕获
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
println!("2 in array1: {}", array1.iter().any(|&x| x == 2));
println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));
//find
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
let mut iter = vec1.iter();//&i32
let mut into_iter = vec2.into_iter();//i32
println!("Find 2 in vec1: {:?}", iter.find(|&&x| x == 2));//`&&i32` to `i32`
println!("Find 2 in vec2: {:?}", into_iter.find(|&x| x == 2));//`&i32` to `i32`
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
println!("Find 2 in array1: {:?}", array1.iter().find(|&&x| x == 2));
println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2));
//position index
let vec = vec![1, 9, 3, 3, 13, 2];
let index_of_first_even_number = vec.iter().position(|x| x % 2 == 0);
assert_eq!(index_of_first_even_number, Some(5));
let index_of_first_negative_number = vec.iter().position(|x| x < &0);
assert_eq!(index_of_first_negative_number, None);
//into_iter这个只能放最后,会消耗集合,会从左到右移动每个元素,之后集合不可用
let index_of_first_even_number = vec.into_iter().position(|x| x % 2 == 0);
assert_eq!(index_of_first_even_number, Some(5));
}
fn higher_order_functions() {
fn is_odd(n: u32) -> bool {
n % 2 == 1
}
println!("Find the sum of all the squared odd numbers under 1000");
let upper = 1000;
let mut acc = 0;
for n in 0.. {//无穷大
let n_squared = n * n;
if n_squared >= upper {
break;
} else if is_odd(n_squared) {
acc += n_squared;
}
}
println!("imperative style: {}", acc);
//函数式风格
let sum_of_squared_odd_numbers: u32 =
(0..).map(|n| n * n)
.take_while(|&n_squared| n_squared < upper)
.filter(|&n_squared| is_odd(n_squared)) // That are odd
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
println!("functional style: {}", sum_of_squared_odd_numbers);
}
fn diverging_functions() {
fn foo() -> ! {
panic!("This call never returns.");
}
//尽管返回值中没有信息,但该函数照常返回。
fn some_fn() {
()
}
let a: () = some_fn();
println!("This function returns and you can see this line.");
//该函数永远不会将控制流返回给调用者。直接抛出恐慌
//let x= panic!("This call never returns.");
println!("You will never see this line!");
fn sum_odd_numbers(up_to: u32) -> u32 {
let mut acc = 0;
for i in 0..up_to {
let addition: u32 = match i % 2 == 1 {
true => i,
false => continue,//不返还,不违反match
};
acc += addition;
}
acc
}
println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9));
//println!("{}", foo()) //error This call never returns.
}
\ No newline at end of file
///函数
pub fn functions() {
fizzbuzz(1);
fizzbuzz_to(1);
methods();
}
fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
//提前返回
if rhs == 0 {
return false;
}
//最后的return 不是必须的
lhs % rhs == 0
}
//没有返回值: ()
fn fizzbuzz(n: u32) -> () {
if is_divisible_by(n, 15) {
println!("fizzbuzz");
} else if is_divisible_by(n, 3) {
println!("fizz");
} else if is_divisible_by(n, 5) {
println!("buzz");
} else {
println!("{}", n);
}
}
//反回: () 可以省略
fn fizzbuzz_to(n: u32) {
for n in 1..n + 1 {
fizzbuzz(n);
}
}
//方法是附加给对象的函数,这些方法可以通过self关键字访问对象及其其他方法的数据
fn methods() {
struct Point {
x: f64,
y: f64,
}
impl Point {
//对象的静态方法
fn origin() -> Point {
Point { x: 0.0, y: 0.0 }
}
fn new(x: f64, y: f64) -> Point {
Point { x, y }
}
}
struct Rectangle {
p1: Point,
p2: Point,
}
impl Rectangle {
fn area(&self) -> f64 {
let Point { x: x1, y: y1 } = self.p1;
let Point { x: x2, y: y2 } = self.p2;
((x1 - x2) * (y1 - y2)).abs()
}
//对象的方法
fn perimeter(&self) -> f64 {
let Point { x: x1, y: y1 } = self.p1;
let Point { x: x2, y: y2 } = self.p2;
2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
}
fn translate(&mut self, x: f64, y: f64) {
self.p1.x += x;
self.p2.x += x;
self.p1.y += y;
self.p2.y += y;
}
}
struct Pair(Box<i32>, Box<i32>);
impl Pair {
fn destroy(self) {
let Pair(first, second) = self;
println!("Destroying Pair({}, {})", first, second);
}
}
let rectangle = Rectangle {
//静态方法使用双冒号
p1: Point::origin(),
p2: Point::new(3.0, 4.0),
};
println!("Rectangle perimeter: {}", rectangle.perimeter());
println!("Rectangle area: {}", rectangle.area());
let mut square = Rectangle {
p1: Point::origin(),
p2: Point::new(1.0, 1.0),
};
square.translate(1.0, 1.0);
let pair = Pair(Box::new(1), Box::new(2));
pair.destroy();
}
use std::fmt;
use std::fmt::{Display, Error, Formatter};
use crate::closures::*;
use crate::conversion::*;
use crate::custom_types::*;
use crate::flow_control::*;
use crate::formatted_print::*;
use crate::functions::*;
use crate::primitives::*;
use crate::types::*;
use crate::variable_bindings::*;
pub mod formatted_print;
pub mod functions;
pub mod flow_control;
pub mod closures;
pub mod conversion;
pub mod types;
pub mod primitives;
......@@ -25,4 +29,6 @@ fn main() {
types();
conversion();
flow_control();
functions();
closures();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册