• 函数与方法
    • 函数
    • 匿名函数
    • 高阶函数
    • 方法

    函数与方法

    函数

    要声明一个函数,需要使用关键字fn,后面跟上函数名,比如

    1. fn add_one(x: i32) -> i32 {
    2. x + 1
    3. }

    其中函数参数的类型不能省略,可以有多个参数,但是最多只能返回一个值,
    提前返回使用return关键字。Rust编译器会对未使用的函数提出警告,
    可以使用属性#[allow(dead_code)]禁用无效代码检查。

    Rust有一个特殊特性适用于发散函数 (diverging function),它不返回:

    1. fn diverges() -> ! {
    2. panic!("This function never returns!");
    3. }

    其中panic!是一个宏,使当前执行线程崩溃并打印给定信息。返回类型!可用作任何类型:

    1. let x: i32 = diverges();
    2. let y: String = diverges();

    匿名函数

    Rust使用闭包 (closure) 来创建匿名函数:

    1. let num = 5;
    2. let plus_num = |x: i32| x + num;

    其中闭包plus_num借用了它作用域中的let绑定num。如果要让闭包获得所有权,
    可以使用move关键字:

    1. let mut num = 5;
    2. {
    3. let mut add_num = move |x: i32| num += x; // 闭包通过move获取了num的所有权
    4. add_num(5);
    5. }
    6. // 下面的num在被move之后还能继续使用是因为其实现了Copy特性
    7. // 具体可见所有权(Owership)章节
    8. assert_eq!(5, num);

    高阶函数

    Rust 还支持高阶函数 (high order function),允许把闭包作为参数来生成新的函数:

    1. fn add_one(x: i32) -> i32 { x + 1 }
    2. fn apply<F>(f: F, y: i32) -> i32
    3. where F: Fn(i32) -> i32
    4. {
    5. f(y) * y
    6. }
    7. fn factory(x: i32) -> Box<Fn(i32) -> i32> {
    8. Box::new(move |y| x + y)
    9. }
    10. fn main() {
    11. let transform: fn(i32) -> i32 = add_one;
    12. let f0 = add_one(2i32) * 2;
    13. let f1 = apply(add_one, 2);
    14. let f2 = apply(transform, 2);
    15. println!("{}, {}, {}", f0, f1, f2);
    16. let closure = |x: i32| x + 1;
    17. let c0 = closure(2i32) * 2;
    18. let c1 = apply(closure, 2);
    19. let c2 = apply(|x| x + 1, 2);
    20. println!("{}, {}, {}", c0, c1, c2);
    21. let box_fn = factory(1i32);
    22. let b0 = box_fn(2i32) * 2;
    23. let b1 = (*box_fn)(2i32) * 2;
    24. let b2 = (&box_fn)(2i32) * 2;
    25. println!("{}, {}, {}", b0, b1, b2);
    26. let add_num = &(*box_fn);
    27. let translate: &Fn(i32) -> i32 = add_num;
    28. let z0 = add_num(2i32) * 2;
    29. let z1 = apply(add_num, 2);
    30. let z2 = apply(translate, 2);
    31. println!("{}, {}, {}", z0, z1, z2);
    32. }

    方法

    Rust通过impl关键字在structenum或者trait对象上实现方法调用语法 (method call syntax)。
    关联函数 (associated function) 的第一个参数通常为self参数,有3种变体:

    • self,允许实现者移动和修改对象,对应的闭包特性为FnOnce
    • &self,既不允许实现者移动对象也不允许修改,对应的闭包特性为Fn
    • &mut self,允许实现者修改对象但不允许移动,对应的闭包特性为FnMut

    不含self参数的关联函数称为静态方法 (static method)。

    1. struct Circle {
    2. x: f64,
    3. y: f64,
    4. radius: f64,
    5. }
    6. impl Circle {
    7. fn new(x: f64, y: f64, radius: f64) -> Circle {
    8. Circle {
    9. x: x,
    10. y: y,
    11. radius: radius,
    12. }
    13. }
    14. fn area(&self) -> f64 {
    15. std::f64::consts::PI * (self.radius * self.radius)
    16. }
    17. }
    18. fn main() {
    19. let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
    20. println!("{}", c.area());
    21. // use associated function and method chaining
    22. println!("{}", Circle::new(0.0, 0.0, 2.0).area());
    23. }