Scala类成员和构造函数参数名称冲突 [英] Scala class members and constructor parameters name clash

查看:158
本文介绍了Scala类成员和构造函数参数名称冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下用Java编写的类:

Consider the following class written in Java:

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

它定义了一个名为 value的最终字段在构造函数中初始化,方法是使用名为alike的参数并将其应用到函数。

It defines a final field called value that is initialized in the constructor, by taking its parameter called alike and applying a function to it.

我想在Scala中编写类似的内容。最初,我尝试过:

I want to write something similar to it in Scala. At first, I tried:

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

但是编译器抱怨:错误:方法值重载需要结果类型

显然,编译器认为表达式内的表达式 value Math.abs(value)是指所定义的方法。因此,所定义的方法是递归的,因此我需要说明其返回类型。因此,我编写的代码没有实现我的预期:我想要在 Math.abs(value) value c>引用构造函数参数 value ,而不引用所定义的方法。好像编译器在 Math.abs(this.value)中隐式添加了 this。

Obviously the compiler thinks that the expression value inside the expression Math.abs(value) refers to the method being defined. Therefore, the method being defined is recursive, so I need to state its return type. So, the code I wrote does not do what I expected it to do: I wanted value inside Math.abs(value) to refer to the constructor parameter value, and not to the method being defined. It is as if the compiler implicitly added a this. to Math.abs(this.value).

添加 val var (或

Adding val or var (or private ... variants) to the constructor parameter doesn't seem to help.

所以,我的问题是:我可以定义一个属性吗?与构造函数参数同名,但值可能不同?如果是这样,怎么办?如果不是,为什么?

So, my question is: can I define a property with the same name as a constructor parameter, but maybe a different value? If so, how? If not, why?

谢谢!

推荐答案

不,您不能。在Scala中,构造函数参数是 属性,因此重新定义它们是没有意义的。

No, you can't. In Scala, constructor parameters are properties, so it makes no sense to redefine them.

解决方案自然是使用另一个名称:

The solution, naturally, is to use another name:

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

像这样使用, initValue 不会成为创建的实例的一部分。但是,如果在 def 或模式匹配声明中使用它,则它将成为该类的每个实例的一部分。

Used like this, initValue won't be part of the instances created. However, if you use it in a def or a pattern matching declaration, then it becomes a part of every instance of the class.

这篇关于Scala类成员和构造函数参数名称冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆