为什么kotlin允许声明变量与方法中的参数同名?

时间:2018-04-05 19:24:43

标签: kotlin

为什么kotlin允许使用与方法内参数相同的名称声明变量?  那么有没有办法访问'隐藏'参数?

示例:

fun main(args: Array<String>) {
    val args = Any()
}

3 个答案:

答案 0 :(得分:9)

Kotlin确实发出了一个关于名字阴影的警告,您可以通过以下方式来抑制:

@Suppress("NAME_SHADOWING")
val args = Any()

在某些情况下,允许这样的阴影可能很方便,例如在参数验证后抛出自定义异常:

fun sample(name: String?) {
    @Suppress("NAME_SHADOWING")
    val name = name ?: throw CustomArgumentRequiredException()
    println(name.length)
}

遗憾的是,无法访问阴影变量。

目前也无法转动a warning into an error

答案 1 :(得分:5)

这称为 shadowing ,它可用于将代码与系统的其他部分分离。这是可能的,因为名称绑定到当前范围。

考虑一下:

您从其他人那里继承了一个类Foo,让我们说一个API。在您的代码中,您引入了变量barFoo的作者也会更新其代码并添加变量bar。如果没有本地范围,就会发生冲突。

顺便说一句,这在包括Java在内的其他JVM基础语言中也是可行的,并且通常在构造函数或setter中使用:

public TestClass(int value, String test) {
    this.value = value;
    this.test = test;
}

public void setFoo(String foo) {
    this.foo = foo;
}

阴影不仅适用于参数,其他东西也可以被遮蔽:字段,方法甚至类。

大多数IDE都会警告你阴影,因为它可能令人困惑。

推荐我们自己的代码:

尝试避免阴影有两个原因:

  • 您的代码变得难以阅读,因为两个不同的东西具有相同的名称,这会导致混淆。
  • 一旦被遮挡,您就无法再访问范围内的原始变量。

答案 2 :(得分:0)

还需要注意的事情,如果尚未实现,或者还有其他新事物出现。在kotlin中,如果没有以var / val为前缀的参数,则无法访问它们,除非将它们添加为属性。因此,如果将基本类定义为:

class Person(name: String, age: Int){

}

在范围内不能使用名称或年龄;但是没有必要遮盖 如miensol所指出的,除了期望的原因之外,但出于基本的考虑。

class Person(name: String, age: Int){
     var name = name 
     var age = age
}

在构造函数中执行这些操作

class Person(var name: String, private var age: Int){           
}

您当然也可以基于在创建的对象上提供的签名来进行访问。

相关问题