lambda 表达式引用的本地变量

【lambda 表达式引用的本地变量】

Bad Example

从 lambda 表达式引用的本地变量必须是 final 变量或实际上的 final 变量。

int i = 0;

// compile-time error
// Variable used in lambda expression should be final or effectively final
// 从 lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
foos.forEach(e -> i++);

JLS # Lambda Body

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

Any local variable used but not declared in a lambda body must be definitely assigned (§16 (Definite Assignment)) before the lambda body, or a compile-time error occurs.

Similar rules on variable use apply in the body of an inner class (§8.1.3). The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.

From 15.27.2. Lambda Body

如果 lambda 里的 本地变量 不是 final 可能会引入并发问题,限制为 final 减少了程序员的负担。

所以这是个 人为限制,而不是技术上不能实现。

突破限制

I know what I'm doing 的前提下,可以突破这层限制,比如 JLS 说的并发问题,那在非并发环境下,就可以去突破下。

单元素数组

int[] i = {0};
foos.forEach(e -> i[0]++);

(匿名)对象封装

// 这里使用的是 java11
var ref = new Object() {
    int i = 0;
};
foos.forEach(e -> ref.i++);

AtomicXxx

AtomicInteger i = new AtomicInteger(0);

// AtomicXxx 用对了,那并发环境也不是问题
foos.forEach(e -> i.getAndIncrement());

本质上其实 AtomcXxx(匿名)对象封装 封装是一种,只是前者是 JDK 写好的,后者则需要自定义。

在Qt中,lambda表达式可以引用变量,通过捕获列表来控制对外部变量的访问。默认情况下,lambda表达式按值捕获外部变量,即复制一份外部变量的值。这意味着,lambda表达式无法修改通过复制方式捕获的外部变量。如果希望修改这些变量,我们需要使用引用方式进行捕获。例如,使用"[&]"来按引用捕获所有外部变量。然后在lambda表达式中,可以直接修改这些变量的值。 使用lambda表达式引用变量的一个重要注意事项是延迟调用。在lambda表达式定义之后,如果外部变量发生了修改,lambda表达式仍然会使用最初捕获到的变量值。例如,如果按值捕获了一个外部变量,然后修改了这个变量的值,lambda表达式仍然会使用最初捕获到的值。 需要注意的是,lambda表达式的语法形式可简单归纳如下: ``` [capture list](parameters) -> return type { body } ``` 其中,捕获列表用于指定需要捕获的外部变量,参数列表和返回类型用于指定lambda表达式的参数和返回值类型,以及函数体用于实现具体的功能。 在Qt中,lambda表达式可以方便地定义和使用函数对象。捕获的外部变量将成为lambda表达式的成员变量,并可以在函数体中访问。值得注意的是,没有捕获变量lambda表达式可以直接转换为函数指针,而捕获变量lambda表达式则不能转换为函数指针。 总结起来,Qt中的lambda表达式可以引用变量,并通过捕获列表来控制对外部变量的访问。可以按值或按引用捕获外部变量,并在lambda表达式中访问和修改这些变量的值。使用lambda表达式可以方便地定义和使用函数对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lixifun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值