代码之家  ›  专栏  ›  技术社区  ›  Bruno Reis

Scala类成员和构造函数参数名称冲突

  •  20
  • Bruno Reis  · 技术社区  · 14 年前

    class NonNegativeDouble {
        private final double value;
        public NonNegativeDouble(double value) {
            this.value = Math.abs(value);
        }
        public double getValue() { return value; }
    }
    

    value

    class NonNegativeDouble(value: Double) {
      def value = Math.abs(value)
    }
    

    但是编译器抱怨:

    显然编译器认为表达式 在表达式内部 Math.abs(value) 价值 里面 数学.abs(值) 引用构造函数参数 this. Math.abs(this.value)

    添加 val var (或 private ... 构造函数参数的变量)似乎没有帮助。

    谢谢!

    4 回复  |  直到 14 年前
        1
  •  18
  •   Tomasz Nurkiewicz    13 年前

    不,不能。在Scala中,构造函数参数

    当然,解决方法是使用另一个名称:

    class NonNegativeDouble(initValue: Double) {
      val value = Math.abs(initValue)
    }
    

    像这样使用, initValue def 或者一个模式匹配声明,则它成为类的每个实例的一部分。

        2
  •  4
  •   soulmachine    12 年前

    @丹尼尔C.索布拉尔

    class NonNegativeDouble(initValue: Double) {
      val value = Math.abs(initValue)
    }
    

    你的代码是对的,但是“构造函数参数是属性”,这是不对的。

    A post from the official site said ,

    类Foo(x:Int)这样的参数如果是

    马丁的回答证实了这一点:

    这都是事实,但它应该被视为一个实现 技术。这就是为什么规范对此保持沉默。

    因此,通常情况下,我们仍然可以将主构造函数参数视为普通方法参数,但是当这些参数被任何方法引用时,编译器会巧妙地将其转换为私有字段。

    如果任何形式参数前面有val,编译器将生成getter定义自动.ifvar,另外生成一个setter。见语言规范第5.3节。

    这些都是关于主构造函数参数的。

        3
  •  2
  •   Rogach    12 年前

    可以考虑参数化字段

    class NonNegativeDouble(val value: Double, private val name: String ){
      if (value < 0) throw new IllegalArgumentException("value cannot be negative")
      override def toString = 
        "NonNegativeDouble(value = %s, name = %s)" format (value, name)
    }
    
    val tom = "Tom"
    val k = -2.3
    
    val a = new NonNegativeDouble(k.abs, tom)
    a: NonNegativeDouble = NonNegativeDouble(value = 2.3, name = Tom)
    
    a.value
    res13: Double = 2.3
    
    a.name
    <console>:12: error: value name in class NonNegativeDouble cannot be accessed in NonNegativeDouble
         a.name
    
    val b = new NonNegativeDouble(k, tom)
    java.lang.IllegalArgumentException: value cannot be negative
    ...
    

    它定义了具有相同名称“value”、“name”的字段和参数。 可以添加修改器,例如private。。。

        4
  •  0
  •   Lord of the Goo    11 年前

    如果是 case classes

    case class NonNegativeDouble(private val initValue: Double) {
      val value = Math.abs(initValue)
      def copy(value: Double = this.value) = NonNegativeDouble(value)
    }
    

    实施 copy 是必需的,以防止将绑定 initValue 争论。

    我希望编译器足够聪明,不会为 初始值