函数
函数定义
1
2
3
|
fn fun(v:i32) -> i32{
v + 3
}
|
定义类型以及返回类型,同时在Rust函数是一个表达式,也就是不需要return。
方法
1
2
3
4
5
6
7
|
struct Pair(Box<i32>, Box<i32>);
impl Pair {
fn destory(self) {
let Pair(x,y) = self;
println!("Destroying Pair({}, {})", x, y);
}
}
|
闭包(也称之为lambda表达式)
1
2
3
|
fn function(i: i32) -> i32 { i + 1 }
let closure_annotated = |i: i32| -> i32 { i + 1 };
let one = || 1;
|
下面看一下指针借用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
fn main() {
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());
// ^ Uncommenting above line will result in compile-time error
// because borrow checker doesn't allow re-using variable after it
// has been moved.
// Removing `move` from closure's signature will cause closure
// to borrow _haystack_ variable immutably, hence _haystack_ is still
// available and uncommenting above line will not cause an error.
}
|
如果变量已经被其他变量借用,那么就无法再次使用该变量,遵循的原则就是一个变量只能允许有一个引用。
FnOnce/Fn/FnMut
这三个困恼了很长时间,感谢网上的资源,现在终于理解了。
首先这三个都是traits
,当闭包作为一个参数传入的时候,需要指定是什么类型,也就是是上述哪种?然后Rust编译器才能够进行检查。
- FnOnce:参数类型是 self,所以,这种类型的闭包会获取变量的所有权,生命周期只能是当前作用域,之后就会被释放了。
- Fn:参数类型是 &self,所以,这种类型的闭包是不可变借用,不会改变变量,也不会释放该变量。所以可以运行多次。
- FnMut:参数类型是 &mut self,所以,这种类型的闭包是可变借用,会改变变量,但不会释放该变量。所以可以运行多次。
FnOnce
1
2
3
4
5
6
7
8
9
10
|
fn apply_once<F>(f: F) where
F: FnOnce() {
f();
}
let x = Box::new(3);
let fun = || {
println!("{}", x);
mem::drop(x);
};
|
在这里,函数fun
只能运行一次,因为运行一次之后x被释放了。其中Box为堆分配函数。
FnMut
1
2
3
4
5
6
7
8
9
10
11
|
fn apply_mut<F>(mut f: F) where
F: FnMut() {
f();
f();
}
let mut e = "xxx".to_string();
let f = || {
e += "xxx"
};
apply_mut(f);
|
这里函数f
能够被运行多次,同时修改了变量的值。
Fn
1
2
3
4
5
6
7
8
9
10
|
fn apply<F>(f: F) where
F: Fn() {
f();
f();
}
let f = || {
println!("{}", "fnn")
};
apply(f);
|
这里的闭包是不可变借用,不会改变变量,也不会释放该变量。所以可以运行多次。
闭包作为返回参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
fn create_fn() -> impl Fn() {
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)
}
fn main() {
let fn_plain = create_fn();
let mut fn_mut = create_fnmut();
let fn_once = create_fnonce();
fn_plain();
fn_mut();
fn_once();
}
|
标准库中的闭包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
let array1 = [1, 2, 3];
println!("2 in array1: {}", array1.iter().any(|&x| x == 2));
println!("Find 2 in array1: {:?}", array1.iter().find(|&&x| x == 2));
let upper = 12;
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))
.fold(0, |acc, n_squared| acc + n_squared);
//高阶函数的用法
fn main() {
let mut acc = 0;
for i in 0..=3 {
let a :u32 = match i % 2 ==1 {
true => i,
false => continue,
};
acc += a;
}
println!("{}", acc);
}
|
参考