Lambda表达式
C++ Lambda 表达式
C++ 的 Lambda 表达式 是一种轻量级的 匿名函数,用于临时定义函数对象,常用于算法、回调、并发、事件响应等场景。
Lambda 表达式是定义内联函数的简洁方式,允许捕获外部变量,并在需要函数对象的地方直接使用。
一、基本语法
[capture](parameter_list) -> return_type { body }
各部分含义如下:
部分 | 含义 |
---|---|
[] |
捕获列表(capture) |
() |
参数列表 |
-> |
返回值类型(可省略) |
{} |
函数体 |
二、基础例子
auto add = [](int a, int b) { return a + b; };
std::cout << add(3, 4); // 输出 7
也可以直接传给函数:
std::vector<int> v = {1, 2, 3};
std::for_each(v.begin(), v.end(), [](int x) {
std::cout << x << " ";
});
三、捕获列表(最关键)
1. 按值捕获(copy)
int x = 10;
auto f = [x]() { std::cout << x << std::endl; };
2. 按引用捕获(reference)
int x = 10;
auto f = [&x]() { x += 1; };
3. 捕获所有变量
捕获方式 | 含义 |
---|---|
[=] |
捕获所有外部变量的副本(按值) |
[&] |
捕获所有外部变量引用(按引用) |
[=, &y] |
所有按值,但 y 按引用 |
[&, x] |
所有按引用,但 x 按值 |
四、结合 STL 使用(常用)
std::vector<int> v = {1, 2, 3, 4};
int threshold = 2;
v.erase(std::remove_if(v.begin(), v.end(), [threshold](int x) {
return x <= threshold;
}), v.end());
五、可变 lambda(mutable)
默认按值捕获的变量是只读的,想修改需加 mutable
:
int x = 0;
auto f = [x]() mutable { x++; std::cout << x; };
f(); // 输出 1(但不影响外部的 x)
六、返回类型推导 & 显式指定
auto f = [](int a, int b) -> double {
return a / (double)b;
};
如果只有一条 return
,可以省略 ->
:
auto f = [](int a, int b) { return a + b; }; // 推导为 int
在 C++ 中,Lambda 表达式是一种定义匿名函数对象的简洁方式,非常适合用于一次性使用的函数逻辑,尤其是在算法或回调中。
七、使用 std::function
存储 Lambda 表达式
#include <iostream>
#include <functional>
using namespace std;
int main() {
function<int(int, int)> add = [](int a, int b) -> int {
return a + b;
};
cout << "Sum of 3 and 4 is: " << add(3, 4) << endl; // 输出:7
return 0;
}
八、Lambda 是函数对象(类)
auto f = [](int x) { return x * 2; };
struct LambdaEquivalent {
int operator()(int x) const { return x * 2; }
};
所以可以存入 std::function
:
std::function<int(int)> func = [](int x) { return x * 2; };
九、Lambda 用于并发(线程/异步)
std::thread t([] {
std::cout << "Hello from thread!" << std::endl;
});
t.join();
十、总结表格
特性 | 示例 | 说明 |
---|---|---|
无捕获 | [](){} |
无依赖环境 |
按值捕获 | [x](){} |
捕获 x 的副本 |
按引用捕获 | [&x](){} |
修改外部变量 |
捕获所有 | [=] / [&] |
简洁,常用于泛用 lambda |
mutable | [x]() mutable { x++; } |
允许修改副本 |
返回类型 | -> T |
用于多类型或精确控制 |
Java Lambda 表达式
在Java中,Lambda表达式是在Java 8引入的,它提供了一种更简洁的方式来表示匿名方法。Lambda表达式可以被用作函数式接口(只有一个抽象方法的接口)的实例。以下是Lambda表达式的基本语法和一些使用场景:
基本语法
(parameters) -> expression
或者
(parameters) -> { statements; }
parameters
:参数列表,它可以为空,也可以包含一个或多个参数。->
:Lambda操作符,读作"goes to"。expression
或{ statements; }
:你希望执行的代码体。如果只有一行语句,可以省略大括号和return关键字;如果有多条语句,则需要使用大括号,并且显式地写return语句(如果需要返回值的话)。
示例
- 无参数的Lambda表达式
假设有一个函数式接口Runnable
,我们可以这样使用Lambda表达式:
Runnable runnable = () -> System.out.println("Hello World");
new Thread(runnable).start();
- 带有一个参数的Lambda表达式
对于Consumer<String>
接口,你可以这样定义一个Lambda表达式:
Consumer<String> consumer = (str) -> System.out.println(str);
consumer.accept("Hello, Lambda!");
- 带有多个参数的Lambda表达式
比如,使用BiFunction<Integer, Integer, Integer>
来计算两个数之和:
BiFunction<Integer, Integer, Integer> adder = (a, b) -> a + b;
System.out.println(adder.apply(5, 3)); // 输出8
使用场景
Lambda表达式非常适合用于集合的遍历、过滤和映射等操作,尤其是在与Stream API一起使用时。例如:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
在这个例子中,我们首先创建了一个字符串列表,然后使用stream()
方法将其转换为流。接着,我们使用filter
方法和Lambda表达式来筛选出以"A"开头的名字,最后使用forEach
方法打印每个名字。
Lambda表达式的引入极大地简化了Java代码的编写,特别是在处理集合数据时。同时,它们也使得代码更加易读和简洁。
Python中的lambda表达式
在 Python 中,lambda
表达式(也称为 匿名函数)是一种创建简单、一次性使用的函数的方式。它不像普通函数那样使用 def
关键字定义,而是使用 lambda
关键字,并且通常用于需要函数对象作为参数的场合,比如在 map()
、filter()
、sorted()
等函数中。
基本语法
lambda arguments: expression
arguments
:可以是多个参数,用逗号分隔。expression
:是一个表达式,其结果就是这个 lambda 函数的返回值。
⚠️ 注意:lambda 函数没有
return
语句,它的返回值就是表达式的结果。
示例
1. 无参数的 lambda 表达式
greet = lambda: "Hello, world!"
print(greet()) # 输出:Hello, world!
2. 单个参数的 lambda 表达式
square = lambda x: x * x
print(square(5)) # 输出:25
3. 多个参数的 lambda 表达式
add = lambda a, b: a + b
print(add(3, 4)) # 输出:7
4. 在 map()
中使用 lambda
将列表中的每个元素平方:
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # 输出:[1, 4, 9, 16]
5. 在 filter()
中使用 lambda
筛选出偶数:
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # 输出:[2, 4, 6]
6. 在 sorted()
或 sort()
中使用 lambda
按字符串长度排序:
words = ["banana", "apple", "cherry", "date"]
sorted_words = sorted(words, key=lambda word: len(word))
print(sorted_words) # 输出:['date', 'apple', 'banana', 'cherry']
7. lambda 与条件表达式结合
max_val = lambda a, b: a if a > b else b
print(max_val(10, 20)) # 输出:20
lambda vs def 函数的区别
特性 | lambda 表达式 | 普通函数 (def ) |
---|---|---|
是否有名字 | 可以匿名 | 必须有名字 |
功能复杂度 | 简单的一行表达式 | 可以包含多条语句和逻辑 |
是否可复用 | 不适合重复使用 | 可复用 |
返回值 | 自动返回表达式结果 | 需要显式使用 return |
使用场景建议
- 临时使用一次的小函数
- 作为参数传递给其他高阶函数(如 map、filter、sorted)
- 提高代码简洁性和可读性(但不要过度使用导致难以理解)
注意事项
- Lambda 表达式只能写一行表达式,不能包含复杂的语句或循环。
- 虽然可以嵌套 lambda,但会降低可读性,不推荐。
未经作者同意请勿转载
本文来自博客园作者:aixueforever,原文链接:https://www.cnblogs.com/aslanvon/p/18961956