不应在Scala中使用案例类?

时间:2010-01-22 18:35:29

标签: scala

Scala中的案例类是使用模式匹配增强的标准类,等于......(或者我错了?)。此外,他们的实例不需要“新”关键字。在我看来,它们比常规类更容易定义(或者我又错了?)。

有很多网页告诉他们应该在哪里使用(主要是关于模式匹配)。但他们应该避免在哪里?为什么我们不在任何地方使用它们?

4 个答案:

答案 0 :(得分:20)

有很多案例类不合适的地方:

  • 当人们希望隐藏数据结构时。
  • 作为超过两个或三个级别的类型层次结构的一部分。
  • 当构造函数需要特殊注意时。
  • 当提取器需要特殊考虑时。
  • 当相等和哈希码需要特殊考虑时。

有时这些要求会在设计中出现,并且需要将一个案例类转换为普通类。由于案例类的好处实际上并不是那么好 - 除了他们专门制作的少数特殊案例 - 我自己的建议是来制作任何案例类,除非有一个明确使用它。

或者换句话说,不要过度设计。

答案 1 :(得分:16)

继承案例类是有问题的。假设你有这样的代码:

case class Person(name: String) { }

case class Homeowner(address: String,override val name: String)
  extends Person(name) { }

scala> Person("John") == Homeowner("1 Main St","John")
res0:  Boolean = true

scala> Homeowner("1 Main St","John") == Person("John")
res1: Boolean = false

也许这就是你想要的,但通常你想要== b当且仅当b == a。不幸的是,编译器无法自动为您解决此问题。

这变得更糟,因为Person("John")的hashCode与Homeowner("1 Main St","John")的hashCode不同,所以现在等于行为奇怪的 hashCode行为很奇怪。

只要您知道会发生什么,继承案例类就可以给出可理解的结果,但它已经被视为不良形式(因此在2.8中已被弃用)。

答案 2 :(得分:1)

Programming in Scala中提到的一个缺点是,由于为case类自动生成的东西,对象变得比正常类大,所以如果内存效率很重要,你可能想要使用常规类。 / p>

答案 3 :(得分:0)

使用case类可能很诱人,因为你想要自由的toString / equals / hashCode。这可能会导致问题,因此请避免这样做。

我确实希望有一个注释可以让你在不制作案例类的情况下获得那些方便的东西,但也许这比听起来更难。