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 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值