Kotlin 中 return 语句的设计是基于怎样的考虑? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CYKun
V2EX    Kotlin

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

  •  2
     
  •   CYKun 2017-05-26 00:20:05 +08:00 7411 次点击
    这是一个创建于 3123 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    fun foo(ints: IntArray) { ints.forEach { if (it == 0) return print(it) } } fun bar(ints: IntArray) { ints.forEac(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) } } 

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

    12 条回复    2017-05-26 10:16:04 +08:00
    jarlyyn
        1
    jarlyyn  
       2017-05-26 03:19:36 +08:00
    ……

    我接触过的大部分语言都是这样啊。
    disposablexyz
        2
    disposablexyz  
       2017-05-26 04:05:44 +08:00 via iPad
    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
        3
    geelaw  
       2017-05-26 04:29:43 +08:00
    问题……为什么不把 return@forEach 语法糖成 continue ?
    imcj
        4
    imcj  
       2017-05-26 07:52:00 +08:00 via iPhone
    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
        5
    wweir  
       2017-05-26 08:20:51 +08:00 via Android   1
    lambda 表达式没有做任何显示的标记,直接把后续代码做隐式替换,导致代码逻辑和直观存在偏差

    感觉这种语法糖不要也罢
    wotemelon
        6
    wotemelon  
       2017-05-26 08:27:10 +08:00 via Android
    js 就是这样的
    araraloren
        7
    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
        8
    araraloren  
       2017-05-26 08:34:41 +08:00
    补充楼上:
    sub ($para) {
    -> {
    return ; # 从 sub 中返回
    }
    }
    设计正好相反。。 :)
    laxenade
        9
    laxenade  
       2017-05-26 08:53:53 +08:00
    感觉叫 yield 更贴切
    SoloCompany
        10
    SoloCompany  
       2017-05-26 09:21:29 +08:00 via iPhone
    这要看定义,inline function 和普通 function 毕竟还是有很大不同的,如果没有这个特性,很多封装控制流的的库函数比如 use run let 等的使用就体验大打折扣了
    enenaaa
        11
    enenaaa  
       2017-05-26 09:22:23 +08:00
    @wweir 赞同。 函数的形式应该一致, 匿名函数搞得像代码块, 容易混淆。
    bombless
        12
    bombless  
       2017-05-26 10:16:04 +08:00 via Android
    有点把问题复杂化了。感觉最好是只要有歧义就强制加 label
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2487 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 01:10 PVG 09:10 LAX 17:10 JFK 20:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86