gpt4 book ai didi

lambda - Kotlin Any 和 lambda

转载 作者:行者123 更新时间:2023-12-02 04:33:32 25 4
gpt4 key购买 nike

虽然随问题提供的代码相当琐碎,但问题侧重于类型安全的更一般方面:

让我们有一个像这样的 lambda 函数:

{it: (Any) -> Any -> it(it)}

它接受另一个 lambda 并以自身作为参数执行它。因此,让我们做一些显而易见的事情,并以自身作为参数调用它:

{it: (Any) -> Any -> it(it)}.apply { this.invoke(this) }

但这并不像我想的那样有效:我在编译时收到以下错误:

类型不匹配:推断类型是 ((Any) -> Any) -> Any 但 (Any) -> Any 是预期的

好的。那么让我们试试这个:

val lambda: (Any) -> Any = { Unit }

这个属性的实际值并不重要,我对结果不感兴趣,只对编译器行为感兴趣。所以这是另一个属性:

 val kappa: (Any) -> Any = lambda

好的,现在这实际上编译了。但这不是和以前一样吗?我将一个 (Any) -> Any 函数传递给一个属性(在另一种情况下它是一个参数),它需要一个 (Any) -> Any 函数。逻辑告诉我:是的,(Any) -> AnyAny 类型,因为一切都是。但为什么这不适用于 lambda 调用?事实上,我可以将我的 lambda 显式转换为 (Any) -> Any 函数,这将导致未经检查的转换,但它会按预期编译和执行 StackOverflowError。

{it: (Any) -> Any -> it(it)}.apply { this.invoke(this as (Any) -> Any) }

区别在哪里?

最佳答案

好的,正如我在评论中所说,在提出这个问题的方式中存在很多无关紧要的混淆。让我们从清理其中的一些开始:

val fn1 = {x1: (Any) -> Any -> x1(x1)}

fn1 的类型是((Any) -> Any) -> Any . x1 的类型是(Any) -> Any .上面的定义编译。 Kotlin 编译器可以毫不费力地看到 x1是一个 Any .

尝试调用 fn1但是,就其本身而言,这是行不通的。 ... 编译器准确说明了原因:fn1是一个 ((Any) -> Any) -> Any 的函数并且不能用作 (Any) -> Any .为什么那行不通?好吧,因为有人可能会引用这个论点!

为了便于讨论,让我们创建第二个函数,与第一个函数非常相似:

val fn2 = {x2: (Any) -> Any -> x2("foo")}

它也可以编译,就好了。现在,整个问题归结为:

为什么这行不通:fn2(fn1)

但在这一点上应该是显而易见的。如果该调用有效(无论涉及多少 applyinvoke 诡计),则尝试调用 x2 (在 fn2 内)无法工作,因为 x2fn1 的别名.这是对 fn1 的调用使用参数 "foo" ,它需要一个函数。

tl;dr:函数的参数类型是逆变的

关于lambda - Kotlin Any 和 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46162015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com