说我在库中有一些案例类:
case class MyClass(a: Int, b: Int)
后来事实证明我的库中存在一个错误,我需要在其中一个参数上应用一些额外的逻辑来保持工作正常,这样就可以从用户的透视实例中实现:
val x = MyClass(1, 2)
println(x.a) // prints '3' or whatever I happen to compute for 'a'
换句话说,x.a
的最终值不一定是传递给构造函数的值。我知道这看起来很疯狂,但相信我,我需要它。在大多数情况下,x.a
仍将返回传递给构造函数的内容,但构造函数参数有一个值会导致错误,我需要对其进行转换。
我看到两种方法来实现这一目标。我可以a
var
:
case class MyClass(var a: Int, b: Int) {
a = someComputation()
}
然后该类变得可变,因为a
可以从外部设置。如果我可以移除或隐藏'我的问题将得到解决。生成的setter但它似乎不可能。如果我添加
private def a_=(newA: Int) {}
它不会覆盖var
生成的setter,因此它会看到两个方法定义并且不会编译。
第二个选项是创建一个与构造函数参数分开的字段/方法:
case class MyClass(private val _a: Int, b: Int) {
val a = someComputation(a)
}
但_a
用于所有特殊生成的方法,例如equals
,toString
等,而自定义字段a
则不具备。< / p>
有没有办法转换构造函数参数而不影响API的其余部分?
答案 0 :(得分:2)
我要做的是覆盖随播对象上的apply
方法,以便通过正确的计算创建MyClass
的实例。
object MyClass {
def apply(a: Int, b: Int) = new MyClass(someComputation(a),b))
}
然后您可以将其称为val x = MyClass(1, 2)
,但如果您仍希望进行计算,则无法像val x = new MyClass(1, 2)
一样调用它。
相反,我会选择同伴对象的另一种方法,它不是一个很好的解决方案,但它应该有效:
object MyClass {
def create(a: Int, b: Int) = new MyClass(someComputation(a),b))
}
答案 1 :(得分:-2)
那么,你想要MyClass(a=1).a == 2
之类的东西返回true吗?
你真的需要解释为什么这是一个坏主意? ;)
感谢上帝,这是不可能的!