高效的交换机需要自我鉴定吗?

fre*_*low 6 lookup constants switch-statement kotlin

显然,when表达式的编译方式不同,具体取决于表示常量的方式:

object SwitchOverConstants {
    val foo = 1
    val bar = 2
    val baz = 3

    fun one(x: Int) = when (x) {
        foo -> "foo"
        bar -> "bar"
        baz -> "baz"
        else -> "else"
    }

    fun two(x: Int) = when (x) {
        SwitchOverConstants.foo -> "foo"
        SwitchOverConstants.bar -> "bar"
        SwitchOverConstants.baz -> "baz"
        else -> "else"
    }
}
Run Code Online (Sandbox Code Playgroud)

这是以下字节代码one:

   0: iload_1       
   1: istore_2      
   2: iload_2       
   3: getstatic     #15                 // Field foo:I
   6: if_icmpne     14
   9: ldc           #34                 // String foo
  11: goto          40
  14: iload_2       
  15: getstatic     #22                 // Field bar:I
  18: if_icmpne     26
  21: ldc           #35                 // String bar
  23: goto          40
  26: iload_2       
  27: getstatic     #27                 // Field baz:I
  30: if_icmpne     38
  33: ldc           #36                 // String baz
  35: goto          40
  38: ldc           #38                 // String else
  40: areturn       
Run Code Online (Sandbox Code Playgroud)

这是字节代码two:

   0: iload_1       
   1: tableswitch   { // 1 to 3
                 1: 28
                 2: 33
                 3: 38
           default: 43
      }
  28: ldc           #34                 // String foo
  30: goto          45
  33: ldc           #35                 // String bar
  35: goto          45
  38: ldc           #36                 // String baz
  40: goto          45
  43: ldc           #38                 // String else
  45: areturn       
Run Code Online (Sandbox Code Playgroud)

为什么我需要使用类名来限定常量以获得有效的表查找?

小智 0

你应该用const修饰符标记每个常量,然后优化就会发生。

顺便说一下,在最新的 Kotlin 版本中,这两个函数的字节码是相同的。