Kotlin it隐式变量的遮蔽问题

在Java中lambda表达式的参数/局部变量和类的成员变量是会发生遮蔽(Shadow)现象的,但是lambda的参数/局部变量不会,即便发生多层嵌套(这样会报错,无法通过编译):

Consumer<Integer> consumer = i -> {
    Consumer<Integer> consumer1 = i -> { // error
        int i = 0; // error
    };
};

不过在kotlin中这样写是不会报错的:

val s = str.let { s: String ->
    s.substring(10).let { s: String -> // no error
        s.substring(3)
        val s = 1 // no error
    }
}

虽然在工程应用中没有遮蔽现象的发生是最好的,但上面的kotlin代码中这种显式的遮蔽也没有太大的危害,毕竟这种遮蔽发生在同段代码中肉眼可见的范围内(顶多代码较长的时候鼠标再滚一下),也不会因为外部程序的变化而影响到这段程序的语义。

不过,在kotlin中存在的隐式变量it却很容易导致隐式遮蔽的情况发生。例如:

val s = str.let {
    it.substring(10).let { // no error, but new 'it'
        it.substring(3)
        val it = 1 // no error, but new 'it'
    }
}

不管是标准库中的作用域函数(Scoping Function),但是一般的接受单参lambda作为参数的过程,使用的时候很可能省略唯一参数,那么就会发生上述情况。代码经过多人多次修改,就可能出现问题。

一点点建议

  1. 禁止使用隐式的it变量(意味着禁止了这种隐式的遮蔽);
  2. 当lambda嵌套时,需要显式声明每一个参数的名称,且名称在上下文中唯一(避免了显式的遮蔽);
  3. 仅在简单表达式中使用隐式的it,例如下方这个程序中it有着一目了然的明确意义:
val ints = arrayListOf(1, 2, 3).map { it + 10 }

相关推荐

  1. Kotlin it变量遮蔽问题

    2024-04-01 12:42:04       40 阅读
  2. 【mysql】有关mysql查询类型转换问题

    2024-04-01 12:42:04       60 阅读
  3. Kotlin作用域函数引发遮蔽问题

    2024-04-01 12:42:04       31 阅读
  4. MySQL中转换(Implicit Conversion)

    2024-04-01 12:42:04       24 阅读
  5. 深入理解Qt共享机制

    2024-04-01 12:42:04       71 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-01 12:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-01 12:42:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-01 12:42:04       82 阅读
  4. Python语言-面向对象

    2024-04-01 12:42:04       91 阅读

热门阅读

  1. ListView

    2024-04-01 12:42:04       37 阅读
  2. typeScript8 (接口)

    2024-04-01 12:42:04       35 阅读
  3. JVM–内存模型/垃圾回收流程

    2024-04-01 12:42:04       32 阅读