C++的lambda表达式
Lambda 表达式简介
Lambda 表达式(也称为匿名函数)是一种简洁的语法,用于定义内联函数。它在 C++11 中引入,允许你在需要函数对象的地方直接定义函数,而无需显式命名和声明函数。
基本语法
[capture](parameters) -> return_type {
// function body
}
[capture]:捕获列表,用于从外部作用域捕获变量。可以为空或包含多个变量。(parameters):参数列表,类似于普通函数的参数。-> return_type:返回类型(可选)。如果省略,编译器会自动推导返回类型。{ function body }:函数体,包含具体的逻辑。
捕获列表 ([capture])
捕获列表决定了 lambda 表达式可以访问哪些外部变量:
[]:不捕获任何外部变量。[=]:按值捕获所有外部变量(复制变量的值)。[&]:按引用捕获所有外部变量(引用外部变量)。[var]:按值捕获指定的外部变量var。[&var]:按引用捕获指定的外部变量var。[this]:捕获当前类的this指针,允许访问类成员。
示例
1. 不捕获任何变量
auto add = [](int a, int b) {
return a + b;
};
int result = add(3, 4); // result = 7
2. 按值捕获外部变量
int x = 10;
auto multiply = [x](int y) {
return x * y;
};
int result = multiply(5); // result = 50
3. 按引用捕获外部变量
int x = 10;
auto increment = [&x]() {
x++;
};
increment();
std::cout << x; // 输出 11
4. 捕获所有外部变量(按值)
int x = 10, y = 20;
auto sum = [=]() {
return x + y;
};
int result = sum(); // result = 30
5. 捕获所有外部变量(按引用)
int x = 10, y = 20;
auto modify = [&]() {
x *= 2;
y += 10;
};
modify();
std::cout << x << " " << y; // 输出 20 30
6. 捕获 this 指针
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
void print() {
auto printValue = [this]() {
std::cout << this->value << std::endl;
};
printValue();
}
};
MyClass obj(42);
obj.print(); // 输出 42
java中的lambda表达式
Java 和 Python 中的 Lambda 表达式
虽然 C++、Java 和 Python 都支持 lambda 表达式,但它们在语法和功能上有一些差异。下面分别介绍 Java 和 Python 中的 lambda 表达式,并对比它们与 C++ 的不同之处。
1. Java 中的 Lambda 表达式
基本语法
(parameters) -> expression
或
(parameters) -> { statements; }
parameters:参数列表。expression:单行表达式(如果只有一行代码)。{ statements; }:多行代码块(如果有多个语句)。
示例
1.1 不捕获任何变量
BinaryOperator<Integer> add = (a, b) -> a + b;
int result = add.apply(3, 4); // result = 7
BinaryOperator 是 Java 标准库中的一个函数式接口,位于 java.util.function 包中。它表示一个接受两个输入参数并返回一个相同类型的输出结果的操作。BinaryOperator 是 BiFunction<T, T, T> 的特化版本,其中输入参数和返回值的类型相同。
1.2 捕获外部变量
Java 的 lambda 表达式不能直接修改外部局部变量,但可以访问 final 或事实上的 final 变量(即在初始化后不再改变的变量)。
int x = 10;
BinaryOperator<Integer> multiply = (y) -> x * y;
int result = multiply.apply(5); // result = 50
1.3 使用函数式接口
Java 的 lambda 表达式通常用于实现函数式接口(只有一个抽象方法的接口),如 Comparator、Predicate、Function 等。
List<String> list = Arrays.asList("apple", "orange", "banana");
list.sort((a, b) -> a.compareTo(b));
// 或者使用方法引用
list.sort(String::compareTo);
Python 中的 Lambda 表达式
基本语法
lambda parameters: expression
parameters:参数列表。expression:单行表达式(Python 的 lambda 表达式只能包含一个表达式)。
示例
不捕获任何变量
add = lambda a, b: a + b
result = add(3, 4) # result = 7
捕获外部变量
Python 的 lambda 表达式可以捕获外部变量,并且可以直接修改这些变量(只要变量是可变类型)。
x = 10
multiply = lambda y: x * y
result = multiply(5) # result = 50
在排序中使用
Python 的 sorted 函数和其他内置函数可以接受 lambda 表达式作为键函数。
words = ["apple", "orange", "banana"]
sorted_words = sorted(words, key=lambda word: len(word))
print(sorted_words) # 输出 ['apple', 'banana', 'orange']
def get_length(word):
return len(word)
words = ["apple", "orange", "banana"]
sorted_words = sorted(words, key=get_length)
print(sorted_words) # 输出: ['apple', 'banana', 'orange']
对比与总结
| 特性 | C++ | Java | Python |
|---|---|---|---|
| 语法 | [capture](params) -> type { body } |
(params) -> expression 或 { statements } |
lambda params: expression |
| 捕获外部变量 | 支持多种捕获方式(按值、按引用等) | 只能捕获 final 或事实上的 final 变量 |
自动捕获外部变量 |
| 返回类型推导 | 可以显式指定或省略 | 推导返回类型 | 返回类型由表达式决定 |
| 函数式接口 | 无 | 必须实现函数式接口 | 无 |
| 多行代码支持 | 支持多行代码 | 支持多行代码(用大括号包裹) | 只支持单行表达式 |
总结
- C++ 的 lambda 表达式功能最强大,支持多种捕获方式和多行代码。
- Java 的 lambda 表达式主要用于实现函数式接口,对外部变量的捕获有严格限制。
- Python 的 lambda 表达式简洁,但仅限于单行表达式,适合快速定义简单的匿名函数。
每种语言的 lambda 表达式都有其特点和适用场景,选择时可以根据具体需求和语言特性进行优化。
浙公网安备 33010602011771号