Kotlin 中 return 语句的设计是基于怎样的考虑?

2017-05-26 00:20:05 +08:00
 CYKun

kotlin 中 return 语句会从最近的函数或匿名函数中返回,这意味着下面两个函数是不同的:

fun foo(ints: IntArray) {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

fun bar(ints: IntArray) {
    ints.forEach(fun(value: Int) {
        if (value == 0) return
        print(value)
    })
}

foo 在遇到 0 时会直接返回,bar 遇到 0 时会跳过它继续执行。
foo 的代码看上去很漂亮,forEach 给人一种在用 for 循环的感觉,遇到 return 直接从 foo 中返回,似乎也挺合理的。

但是 forEach 接收的毕竟是一个 lamda 表达式,这种设计导致匿名函数和 lambda 表达式行为不一致,为此 kotlin 还提供了 @Label 来控制返回语句:

fun foo(ints: IntArray) {
    ints.forEach {
        if (it == 0) return@forEach
        print(it)
    }
}

大家觉得这种设计是好是坏?

6971 次点击
所在节点    Kotlin
12 条回复
jarlyyn
2017-05-26 03:19:36 +08:00
……

我接触过的大部分语言都是这样啊。
disposablexyz
2017-05-26 04:05:44 +08:00
https://blog.jooq.org/2016/02/22/a-very-peculiar-but-possibly-cunning-kotlin-language-feature/

"reason is very simple: we want to have lambdas that work exactly like built-in language features (e.g. synchronised)"
geelaw
2017-05-26 04:29:43 +08:00
问题……为什么不把 return@forEach 语法糖成 continue ?
imcj
2017-05-26 07:52:00 +08:00
Now, it returns only from the lambda expression. Oftentimes it is more convenient to use implicits labels: such a label has the same name as the function to which the lambda is passed.

在 lambda 里面 continue 没有意义。
wweir
2017-05-26 08:20:51 +08:00
lambda 表达式没有做任何显示的标记,直接把后续代码做隐式替换,导致代码逻辑和直观存在偏差

感觉这种语法糖不要也罢
wotemelon
2017-05-26 08:27:10 +08:00
js 就是这样的
araraloren
2017-05-26 08:29:15 +08:00
个人觉得不大好,同样对比 Perl 6 的设计
不让你在 Block (lambda) 中使用 return 会报错
Block:
-> $para {
return $para; # ERROR !
}

而匿名的方法则没问题
sub ($para) {
return $para; # OK
}
araraloren
2017-05-26 08:34:41 +08:00
补充楼上:
sub ($para) {
-> {
return ; # 从 sub 中返回
}
}
设计正好相反。。 :)
laxenade
2017-05-26 08:53:53 +08:00
感觉叫 yield 更贴切
SoloCompany
2017-05-26 09:21:29 +08:00
这要看定义,inline function 和普通 function 毕竟还是有很大不同的,如果没有这个特性,很多封装控制流的的库函数比如 use run let 等的使用就体验大打折扣了
enenaaa
2017-05-26 09:22:23 +08:00
@wweir 赞同。 函数的形式应该一致, 匿名函数搞得像代码块, 容易混淆。
bombless
2017-05-26 10:16:04 +08:00
有点把问题复杂化了。感觉最好是只要有歧义就强制加 label

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

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

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

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

© 2021 V2EX