searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Rust函数高级

2025-11-17 10:54:14
0
0

Rust函数高级

1. 函数指针(Function Pointers)

在 Rust 中,函数本身也可以作为值传递,这就是 函数指针 的用法。

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

// f 是一个函数指针,类型是 fn(i32) -> i32
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
    f(arg) + f(arg)
}
  • 函数 add_one 可以作为参数传入 do_twice。
  • 调用 do_twice(add_one, x) 会执行 add_one(x) 两次并相加。
  • 类型写作 fn(i32) -> i32,表示 函数指针类型

特点:函数指针实现了闭包 trait:Fn、FnMut 和 FnOnce。因此可以在期望闭包的地方直接传入函数。

2. 闭包与函数指针的互换

Rust 中的闭包和函数指针可以互换使用,但闭包可以捕获环境变量,函数指针不能。

let list_of_numbers = vec![1, 2, 3];

// 使用闭包
let list_of_strings_1: Vec<String> = list_of_numbers
    .iter()
    .map(|x| x.to_string())
    .collect();

// 使用函数指针
let list_of_strings_2: Vec<String> = list_of_numbers
    .iter()
    .map(ToString::to_string)
    .collect();

3. 返回闭包的问题与解决方案

尝试直接返回闭包会报错:

// 错误示例
fn return_closure() -> Fn(i32) -> i32 {
    |x| x + 1
}
  • 原因:Rust 不知道闭包的具体大小(闭包类型是匿名的,不是固定类型)
  • 解决办法:使用 动态分发(trait 对象) 和 堆分配:
fn return_closure() -> Box<dyn Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}
  • Box<dyn Fn(i32) -> i32>:堆上存储闭包,编译器通过 trait 对象动态分发调用
  • 这样就可以返回闭包并在函数外使用:
let closure = return_closure();
let y = closure(1);
0条评论
作者已关闭评论
陈****然
11文章数
0粉丝数
陈****然
11 文章 | 0 粉丝
陈****然
11文章数
0粉丝数
陈****然
11 文章 | 0 粉丝
原创

Rust函数高级

2025-11-17 10:54:14
0
0

Rust函数高级

1. 函数指针(Function Pointers)

在 Rust 中,函数本身也可以作为值传递,这就是 函数指针 的用法。

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

// f 是一个函数指针,类型是 fn(i32) -> i32
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
    f(arg) + f(arg)
}
  • 函数 add_one 可以作为参数传入 do_twice。
  • 调用 do_twice(add_one, x) 会执行 add_one(x) 两次并相加。
  • 类型写作 fn(i32) -> i32,表示 函数指针类型

特点:函数指针实现了闭包 trait:Fn、FnMut 和 FnOnce。因此可以在期望闭包的地方直接传入函数。

2. 闭包与函数指针的互换

Rust 中的闭包和函数指针可以互换使用,但闭包可以捕获环境变量,函数指针不能。

let list_of_numbers = vec![1, 2, 3];

// 使用闭包
let list_of_strings_1: Vec<String> = list_of_numbers
    .iter()
    .map(|x| x.to_string())
    .collect();

// 使用函数指针
let list_of_strings_2: Vec<String> = list_of_numbers
    .iter()
    .map(ToString::to_string)
    .collect();

3. 返回闭包的问题与解决方案

尝试直接返回闭包会报错:

// 错误示例
fn return_closure() -> Fn(i32) -> i32 {
    |x| x + 1
}
  • 原因:Rust 不知道闭包的具体大小(闭包类型是匿名的,不是固定类型)
  • 解决办法:使用 动态分发(trait 对象) 和 堆分配:
fn return_closure() -> Box<dyn Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}
  • Box<dyn Fn(i32) -> i32>:堆上存储闭包,编译器通过 trait 对象动态分发调用
  • 这样就可以返回闭包并在函数外使用:
let closure = return_closure();
let y = closure(1);
文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0