kotlin:如何解释这两种写法的输出结果的不同?

2020-11-02 23:49:05 +08:00
 Newyorkcity
fun main(args: Array<String>) {
    val list = 1..5;
    println("1:-------------")
    list.forEach(fun(a: Int) {
        if (a == 3) return;
        println(a);
    });
    println("2:-------------")
    list.forEach {
        if (it == 3) return;
        println(it)
    }
}

感兴趣的 V 友可以先自己推断一下输出结果各自是什么..

我说不清楚为什么,有懂的老哥还请赐教。谢谢~!

1247 次点击
所在节点    问与答
10 条回复
ysc3839
2020-11-02 23:54:05 +08:00
目测前面那个输出了 1 2 4 5,后面那个输出了 1 2 。大概是因为前者是从 fun return 了,而后者是从 main return 了。
hoichallenger
2020-11-03 00:02:22 +08:00
上面是匿名函数,下面是 Lambda 表达式,return 的含义当然不一样。只要在下面的 forEach 里使用 Qualified returns ( return@forEach )就可能保证两者结果一致了。
Jirajine
2020-11-03 00:49:09 +08:00
@hoichallenger 这种行为很奇怪,lambda 也是函数,return 应该从最内层函数返回。
不过这种 labeled return 倒是很有用,可惜其他语言没有类似的机制。
bkmi
2020-11-03 01:40:05 +08:00
@Jirajine 这里 lambda 是 inline 的,不是函数。
billlee
2020-11-03 01:45:57 +08:00
Newyorkcity
2020-11-03 07:12:55 +08:00
@hoichallenger return 的含义的不一祥具体是指?
starerlloll
2020-11-03 07:38:28 +08:00
第一个是在 fun(a: Int) { } 里 return, 所以在 prinln 之前结束了该 fun,但这并不影响 list.forEach 继续
第二个是在 list.forEach 里 return, 所以到 3 了就停了
Newyorkcity
2020-11-03 10:56:22 +08:00
@starerlloll
第二个为什么会影响到外面的 forEach 呢?我个人了解这种写法是一个语法糖,当被调用的函数甲所需要的入参为一个函数类型时,可以直接将被调用的函数甲不接(),而接{}并在其中完成入参函数的函数体。。。但语法糖背后的逻辑不应该仍然是函数甲(先具体到 forEach )把每个元素都调用一次函数乙吗?

莫非此时传入函数乙的变成了 list ?
zhtf
2020-11-03 12:16:01 +08:00
hoichallenger
2020-11-03 16:40:39 +08:00
@Newyorkcity Kotlin 的文档里关于 return 是这么说的:By default returns from the nearest enclosing function or anonymous function. 因为 Lambda 是表达式( Expression )不是函数( Function ),所以第二个 forEach 里的 return 最近的函数是 main 函数,而第一个 forEach 里的 return 最近的函数是那个匿名函数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/721191

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX