RustPrimer
  • Introduction
  • 初识Rust
  • 安装Rust
    • Linux
    • Mac
    • Windows
    • 版本管理工具: rustup
  • 编辑器
    • 前期准备
    • vim
    • emacs
    • vscode
    • atom
    • sublime
    • visual studio
    • spacemacs
  • Rust快速入门
    • Rust旅程
    • 变量绑定与原生类型
    • 数组、动态数组和字符串
    • 结构体与枚举
    • 控制流
    • 函数与方法
    • 特性
    • 注释与文档
    • 输入输出流
  • Cargo项目管理器
  • 基本程序结构
    • 注释
    • 条件
    • 循环
  • 类型、运算符和字符串
    • 基础类型
    • 复合类型
    • 字符串类
    • 基础运算符和字符串格式化
  • 函数
    • 函数参数
    • 函数返回值
    • 语句和表达式
    • 高阶函数
  • 模式匹配
    • match关键字
    • 模式 pattern
  • 特征 Trait
    • trait关键字
    • trait对象
  • 泛型
  • 可变性、所有权、租借和生命期
    • 所有权
    • 引用和借用
    • 生命周期
  • 闭包
    • 闭包的语法
    • 闭包的实现
    • 闭包作为参数和返回值
  • 集合类型 Collections
    • 动态数组 Vec
    • 哈希表 HashMap
  • 迭代器
    • 迭代器、适配器、消费者
  • 模块和包系统、Prelude
    • 模块 module 和包 crate
    • Prelude
  • Option、Result与错误处理
  • 输入与输出
  • 宏系统
  • 堆、栈与Box
  • 几种智能指针
    • Rc, Arc
    • Mutex, RwLock
    • Cell, RefCell
  • 类型系统中的几个常见 Trait
    • Into/From 及其在 String 和 &str 互转上的应用
    • AsRef, AsMut
    • Borrow, BorrowMut, ToOwned
    • Deref 与 Deref coercions
    • Cow 及其在 String 和 &str 上的应用
  • Send 和 Sync
  • 并发,并行,多线程编程
    • 线程
    • 消息传递
    • 共享内存
    • 同步
    • 并行
  • Unsafe、原始指针
    • Unsafe
    • 原始指针
  • FFI
    • rust调用ffi函数
    • 将rust编译成库
  • 运算符重载
  • 属性和编译器参数
    • 属性
    • 编译器参数
  • Cargo参数配置
  • 测试与评测
    • 测试 (testing)
    • 评测 (benchmark)
  • 代码风格
  • Any与反射
  • 安全(safe)
  • 常用数据结构实现
    • 栈结构
    • 队列
    • 二叉树
    • 优先队列
    • 链表
    • 图结构
  • 标准库介绍
    • 系统命令:调用grep
    • 目录操作:简单grep
    • 网络模块:W回音
  • 实战篇
    • 实战:Json处理
    • 实战:Web 应用开发入门
    • 实战:使用Postgresql数据库
  • 附录-术语表
Powered by GitBook
On this page
  • 函数
  • 匿名函数
  • 高阶函数
  • 方法

Was this helpful?

  1. Rust快速入门

函数与方法

函数

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

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

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

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

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

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

let x: i32 = diverges();
let y: String = diverges();

匿名函数

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

let num = 5;
let plus_num = |x: i32| x + num;

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

let mut num = 5;

{
    let mut add_num = move |x: i32| num += x;   // 闭包通过move获取了num的所有权

    add_num(5);
}

// 下面的num在被move之后还能继续使用是因为其实现了Copy特性
// 具体可见所有权(Owership)章节
assert_eq!(5, num);

高阶函数

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

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

fn apply<F>(f: F, y: i32) -> i32
    where F: Fn(i32) -> i32
{
    f(y) * y
}

fn factory(x: i32) -> Box<Fn(i32) -> i32> {
    Box::new(move |y| x + y)
}

fn main() {
    let transform: fn(i32) -> i32 = add_one;
    let f0 = add_one(2i32) * 2;
    let f1 = apply(add_one, 2);
    let f2 = apply(transform, 2);
    println!("{}, {}, {}", f0, f1, f2);

    let closure = |x: i32| x + 1;
    let c0 = closure(2i32) * 2;
    let c1 = apply(closure, 2);
    let c2 = apply(|x| x + 1, 2);
    println!("{}, {}, {}", c0, c1, c2);

    let box_fn = factory(1i32);
    let b0 = box_fn(2i32) * 2;
    let b1 = (*box_fn)(2i32) * 2;
    let b2 = (&box_fn)(2i32) * 2;
    println!("{}, {}, {}", b0, b1, b2);

    let add_num = &(*box_fn);
    let translate: &Fn(i32) -> i32 = add_num;
    let z0 = add_num(2i32) * 2;
    let z1 = apply(add_num, 2);
    let z2 = apply(translate, 2);
    println!("{}, {}, {}", z0, z1, z2);
}

方法

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

  • self,允许实现者移动和修改对象,对应的闭包特性为FnOnce。

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

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

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

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    fn new(x: f64, y: f64, radius: f64) -> Circle {
        Circle {
            x: x,
            y: y,
            radius: radius,
        }
    }

    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

fn main() {
    let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
    println!("{}", c.area());

    // use associated function and method chaining
    println!("{}", Circle::new(0.0, 0.0, 2.0).area());
}
Previous控制流Next特性

Last updated 5 years ago

Was this helpful?