我想让apply
一个案例类的自动伴随类构造函数为我执行隐式转换,但不知道该怎么做。我已经到处搜索了,我能找到的最接近的答案是这个问题(我将在下面解释为什么它不是我要找的)。
我有一个看起来像这样的案例类:
case class Container(a: Long, b: Long, c: Long)
我正在使用容器来计算适用某些条件的实例,因此我希望能够让构造函数自动将布尔参数转换为 long ( if (boolean) 1L else 0L
)。
当然,真正的案例类有很多参数,因此制作我自己的伴生对象并重载apply
以接受Boolean
参数将是乏味且非常重复的。此外,像下面的代码这样的东西并不理想(如果它以某种方式正确实现),因为它只接受布尔参数:
object Container {
def apply(args: Boolean*) = {
// doesn't REALLY work since number of arguments not enforced
Container(args map { if (_) 1L else 0L } toArray: _*)
}
}
val c1 = Container(1, 0, 1) // works
val c2 = Container(true, false, true) // might be workable if done correctly
val c3 = Container(true, 0, 1) // won't work
我尝试在伴生对象中添加一个隐式转换(如下),希望它会自动在 中使用Container.apply
,但似乎这实际上并没有将隐式转换放入调用 apply 的代码的命名空间中。
object Container {
implicit def booleanToLong(x: Boolean): Long = if (x) 1L else 0L
}
我可以使用这种骇人听闻的解决方法使事情正常进行:
{
import Container.booleanToLong
// all of these now work
val c1 = Container(1, 0, 1)
val c2 = Container(true, false, true)
val c3 = Container(true, 0, 1) // works!!!
}
最大的问题是我必须导入booleanToLong
想要创建 a 的代码,Container
因此必须将它放在自己的块中以确保安全(booleanToLong
通常是不可取的)。
最后,使用本身包含隐式转换的隐式参数的解决方案不起作用,因为它需要显式覆盖apply
,从而破坏了不重复长参数列表和封送类型的目标。
有没有办法做到这一点,这样我每次做 a 时都可以免费获得隐式转换Container
,但不是这样?还是由于某种技术限制,这是不可能的?