【问题标题】:Evaluate code block in Kotlin (to hide variables inside scope)评估 Kotlin 中的代码块(在范围内隐藏变量)
【发布时间】:2019-04-03 15:37:56
【问题描述】:

在 Scala 中,您可以编写

val x = {
  ... do some complex computations ..
  42
}

隐藏代码块内的东西。

我最接近 Kotlin 的是:

val x = {
  ... do some complex computations ..
  42
}()

有没有更好的办法?

编辑:

  • 与上述示例中的run {} 基本相同
  • 调用 run 成本高吗?

回答:

  • 使用run {} 内联,而{}() 不使用(请参阅下面我自己的答案)

【问题讨论】:

  • "isn't run {} in the above example基本上相同":它将给出相同的结果,但对run的调用保证是内联的,而对{ ... }()的调用将创建一个函数对象并调用它。
  • @marstran 为什么要创建函数对象? Run 也只是在 pass lambda 上调用 ()
  • 因为run 是一个内联函数。编译器将 lambda 主体复制到调用站点。

标签: kotlin


【解决方案1】:

使用run 函数。它接受一个函数作为参数,运行它并返回结果。

val x = run {
  ... do some complex computations ..
  42
}

run 函数是内联的,因此不会产生性能开销。

【讨论】:

    【解决方案2】:

    是的,有run 函数。

    val x = run {
        ...
        42
    }
    

    【讨论】:

      【解决方案3】:

      你也可以使用这些方法:

       val a=1.also{
          // your code
      }
      val b=2.apply{
          // your code}
      }
      val c=3.let{
          // your code
      }
      val d=4.runCatching{
          // your code
      }
      

      【讨论】:

        【解决方案4】:

        为了在使用run 时验证内联,我创建了一个小示例:

            fun main() {
                {
                    Math.random()
                }()
        
                run {
                    Math.random()
                }
            }
        

        并查看生成的字节码:

          public final static main()V
           L0
            LINENUMBER 2 L0
            GETSTATIC TestKt$main$1.INSTANCE : LTestKt$main$1;
            CHECKCAST kotlin/jvm/functions/Function0
            INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object; (itf)
            POP
           L1
            LINENUMBER 6 L1
           L2
           L3
           L4
            ICONST_0
            ISTORE 0
           L5
            LINENUMBER 7 L5
            INVOKESTATIC java/lang/Math.random ()D
           L6
           L7
            LINENUMBER 6 L7
           L8
            POP2
           L9
            LINENUMBER 9 L9
            RETURN
           L10
            LOCALVARIABLE $i$a$-run-TestKt$main$2 I L5 L7 0
            MAXSTACK = 2
            MAXLOCALS = 1
        
        

        确实如此:

        • 通过() 调用会调用生成的Function0 派生类,该类将块封装为lambda(标签L0
        • 通过run 调用完全内联块(标签L5

        【讨论】:

          猜你喜欢
          • 2013-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多