because ‘job‘ is a local variable that is captured by a changing closure

通常,当在 lambda 函数闭包中捕获可变变量时,智能转换不适用于该变量,无论是在 lambda 内部还是在 lambda 创建后的声明范围内。

这是因为该函数可能会脱离其封闭范围,并可能稍后在不同的上下文中执行,可能多次执行,也可能并行执行。作为一个例子,考虑一个假设的函数 List.forEachInParallel { ... },它为列表的每个元素执行给定的 lambda 函数,但是是并行的。

编译器必须生成即使在这种严重情况下也保持正确的代码,因此它不会假设变量的值在空检查后保持不变,因此不能智能转换它。

但是,List.forEach 完全不同,因为它是一个内联函数。内联函数的主体及其函数参数的主体(除非参数具有 noinline 或 crossinline 修饰符)在调用站点内联,因此编译器可以推断作为参数传递给内联函数的 lambda 中的代码,就好像它直接写在调用方法体中,使智能转换成为可能。

可以,但目前还不行。仅仅是因为该功能尚未实现。它有一个未解决的问题:KT-7186。

分享
改进这个答案
跟随
于 2020 年 7 月 17 日 23:27 编辑

35

+50

In general, when a mutable variable is captured in a lambda function closure, smart casts are not applicable to that variable, both inside the lambda and in the declaring scope after the lambda was created.

It's because the function may escape from its enclosing scope and may be executed later in a different context, possibly multiple times and possibly in parallel. As an example, consider a hypothetical function List.forEachInParallel { ... }, which executes the given lambda function for each element of the list, but in parallel.

The compiler must generate code that will remain correct even in that severe case, so it doesn't make an assumption that the value of variable remains unchanged after the null check and thus cannot smart cast it.

However, List.forEach is quite different, because it is an inline function. The body of an inline function and the bodies of its functional parameters (unless the parameter has noinline or crossinline modifiers) are inlined at the call site, so the compiler could reason about the code in a lambda passed as an argument to inline function as if it was written directly in the calling method body making the smart cast possible.

It could, but currently, it doesn't. Simply because that feature is not implemented yet. There is an open issue for it: KT-7186.

Share

Improve this answer

Follow

edited Jul 17, 2020 at 23:27

kotlin - Compilation error: Smart cast to '<type>' is impossible, because '<variable>' is a local variable that is captured by a changing closure - Stack Overflow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值