Rust函数进阶

文章目录

Rust系列:初步所有权结构体和枚举类

函数

先来回顾一下Rust中函数的创建过程,在Rust中,函数用fn声明,如有传入参数或返回值,都需要声明数据类型,下面是一个质朴的阶乘函数

可以写一个阶乘函数

rust 复制代码
fn fac(x:i32)->i32{
    if x>1{
        return x*fac(x-1);
    }else{
        return 1;
    }
}

fn main(){
    let x = fac(5);
    println!("5!={}",x);
}

测试为

复制代码
>rustc main.rs
>main.exe
5!=120

函数中的函数

Rust中的函数并不支持传入任意参数,如果非要这么干,那么需要用宏来假装实现,故而就等到介绍宏的时候再说。

但Rust提供了一些函数式特性,首先支持在函数中再定义一个函数,示例如下

rust 复制代码
//lambda.rs
fn closure_test_1(){
    fn add(a:i32, b:i32) -> i32 {a + b}
    println!("3+4={}", add(3,4));
}
fn main(){
    closure_test_1();
}

测试结果如下

复制代码
>rustc lambda.rs
>lambda.exe
3+4=7

lambda表达式

函数式编程的一大优势就是把函数当作变量,那么既然是变量,就应该可以用let绑定,而想用let绑定,就必须通过赋值好把函数名和函数内容分开,这就是lambda表达式

Rust中的lambda表达式,从写法上来说,就是用两个竖线代替函数的括号,总共有四种写法,示例如下

rust 复制代码
fn closure_test_2(){
    let add = |a:f32, b:f32| -> f32{a+b};
    let minus = |a,b| {a-b};
    let mul = |a, b| a*b;
    let div = move |a,b| a/b;

    println!("add(3,4)={}", add(3.0,4.0));
    println!("minus(3,4){}", minus(3.0,4.0));
    println!("mul(3,4)={}", mul(3.0,4.0));
    println!("div(3,4)={}", div(3.0,4.0));
}
fn main(){
    closure_test_2();
}

其中,add是比较完整的写法;minus则是简化版本,并且开启了类型判断;mul进一步简化,省略了花括号;div则使用了move关键字,其功能是强制闭包取得被捕获变量的所有权。

运行结果如下

js 复制代码
add(3,4)=7
minus(3,4)-1
mul(3,4)=12
div(3,4)=0.75

函数作为参数

为了明白我们要干什么,下面举一个最简单的示例,新建一个fun_test,这个函数有三个参数,前两个参数是整数,第三个参数是一个可以调用两个参数的函数,示例如下

rust 复制代码
fn fun_test(v1: i32, v2: i32,  
    f: &dyn Fn(i32, i32) -> i32){
    println!("{}", f(v1, v2));
}

fn main() {
    let mul = |a, b| a*b;
    println!("5x8=");
    fun_test(5, 8, &mul);
}

上述代码有个值得注意的地方,首先fun_test第三个参数的类型为&dyn Fn(i32, i32)->i32,即这是个Fn类型的函数,并且用到了取地址符&,并且用到了trait前缀dyn。相应地,在调用fun_test时,其传入参数mul也用到了取地址符。

测试结果如下

rust 复制代码
>lambda.exe
5x8=40

Rust中提供了三种作为参数的函数类型,其限制如下

  • Fn:不能修改捕获的对象。
  • FnMut:可以修改捕获的对象。
  • FnOnce:只能调用一次
相关推荐
段一凡-华北理工大学19 分钟前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
大卫小东(Sheldon)6 小时前
小鹤音形词典:一个用 Rust 写的离线编码查询桌面工具
ai·rust
就业发动机7 小时前
我用 Tauri 做了一个约 1.5 MB 的开源屏幕标注工具:MarkerOn
vue.js·rust
2601_954526759 小时前
【硬核架构】打破 IT 与 OT 的数据孤岛!基于 Rust 异步协程的工业 IoT 网关重构,兼谈顶级自动化智能仪表厂家选型指南
物联网·架构·rust
white_ant9 小时前
17- 文本统计/处理工具使用指南
rust·个人开发·tauri
独孤留白10 小时前
Rust 类型转换全景指南 —— 从引用转换到序列化
rust
独孤留白10 小时前
从C到Rust:Trait TryFrom TryInto 可能失败的类型转换
rust
雨师@11 小时前
python通过rust编写组件扩展自己的能力
python·rust
程序员爱钓鱼13 小时前
Rust 切片 Slice 详解:安全访问连续数据
前端·后端·rust
花褪残红青杏小19 小时前
Rust图像处理第20节-PCA 主成分分析:把图片压缩到 3 个数字
rust·webassembly·图形学