何时使用案例类或常规类

时间:2014-09-30 10:14:12

标签: scala

我有一些误解,在什么情况下我应该使用案例类或常规类遵循最佳实践。我已经阅读过关于两个类的差异但是无法想象自己的实际例子,其中推荐用例或常规类。

有人可以向我展示一些真实的例子,并解释为什么建议这样做而不是其他情况?

6 个答案:

答案 0 :(得分:48)

如果要编写具有不可变对象的纯函数代码,最好使用常规类来尝试避免。 功能范例的主要思想是将数据结构和操作分离。 Case Classes是具有必要方法的数据结构的表示。应在不同的软件实体(例如,特征,对象)中描述数据上的函数。

相反,常规类链接数据和操作以提供可变性。这种方法更接近面向对象的范式。


因此,如果出现以下情况,请不要使用案例类

  1. 你的班级有可变的状态。
  2. 你的课程包括一些逻辑。
  3. 您的课程不是数据表示,您不需要结构平等。
  4. 但是,在这些情况下,您应该考虑代码的样式,因为它可能不够功能。

答案 1 :(得分:11)

案例类是具有语法糖的正常。所以没有真正的重大区别,你可以用一个可以用类做的案例类来做所有事情,反之亦然。

案例类只会为您节省大量的锅炉板代码。

顾名思义,完美契合是模式匹配中的案例类与case的使用。

case class MyCase(name: String, age: Int)

data : List[MyCase] = ...

data foreach { 
    case MyCase(_, age) if age > 21 => println("old enough")
    case MyCase("fred", _ ) => println("Got you")
    case _ => ...
}

答案 2 :(得分:9)

  1. 当你的班级有可变状态时,使用案例类。
  2. 当您想要结构平等时,确实使用案例类,因为它为您提供了正确的hashCodeequals。例如,您希望能够将它们用作SetMap
  3. 的键

    这是另一个更个人的偏好:

    • 如果您只是想要自动获取器,并且将实例放在SetMap中,但您只有一个实例并且不需要结构相等,则首选class Foo(val i: Int) case class Foo(i: Int),因为您没有可能进行更昂贵的平等检查。

    如果1.和2.碰撞,您可以手动实现特定的案例类功能。例如,为可变的非案例类提供伴随apply方法或模式匹配提取器。

答案 3 :(得分:5)

案例类为您提供“免费”(即,您不必编写)equalshashcodetoString以及apply的实现和伴随对象中的unapply。 基本上,您可以将案例类视为命名元组,其字段也可以命名。

对于其他任何事情,你可能最好使用正常的课程。

答案 4 :(得分:1)

普通类是Java中的类。它可以包含状态和功能 案例类就像Java中的数据POJO。保持状态的类,可以由函数使用(通常在其他类中)。

当您在Java中实现数据POJO时,您应该设置它所拥有的变量,为它们添加getter和setter,实现hashcode和equals,并且可能实现toString。
通常它并没有那么糟糕,因为在定义变量之后,IDE可以为您生成所有变量,但是如果您更改/添加变量,那么您应该记得更新所有方法。
在类的情况下,您可以定义变量(或更好的值),编译器会为您生成所有方法。所以你获得了两者,没有样板和更新的功能 对于案例类,编译器还会生成更多功能,您不会在Java中使用复制功能,并且可以在比较对象中应用/取消应用。

答案 5 :(得分:1)

案例类是数据中心的。

通过使用案例类而不是常规类,我们获得了以下优势。

(1)值等价:这意味着可以将两个案例实例与其中的值进行比较。

scala> case class Time(hours: Int = 0, mins: Int = 0)
defined class Time

scala> val time1 = Time(12, 13)
time1: Time = Time(12,13)

scala> val time2 = Time(11, 12)
time2: Time = Time(11,12)

scala> time1 == time2
res6: Boolean = false

scala> val time3 = Time(10, 11)
time3: Time = Time(10,11)

scala> time1 == time2
res7: Boolean = false

但未定义其他比较运算符(>,> =<,等)。

(2)不可变字段:线程安全

(3)自动字段创建:小时分钟是Scala自动创建的不可变字段。

scala> time1.hours
res9: Int = 12

案例类也用于解析spark DataFrame行,优点是可以通过case类的字段名访问DataFrame的列。