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

阅读: 评论:0

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

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

本文发布于:2024-01-29 07:15:08,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170648371313608.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:variable   local   job   closure   changing
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23