我有一些误解,在什么情况下我应该使用案例类或常规类遵循最佳实践。我已经阅读过关于两个类的差异但是无法想象自己的实际例子,其中推荐用例或常规类。
有人可以向我展示一些真实的例子,并解释为什么建议这样做而不是其他情况?
答案 0 :(得分:48)
如果要编写具有不可变对象的纯函数代码,最好使用常规类来尝试避免。 功能范例的主要思想是将数据结构和操作分离。 Case Classes是具有必要方法的数据结构的表示。应在不同的软件实体(例如,特征,对象)中描述数据上的函数。
相反,常规类链接数据和操作以提供可变性。这种方法更接近面向对象的范式。
因此,如果出现以下情况,请不要使用案例类
但是,在这些情况下,您应该考虑代码的样式,因为它可能不够功能。
答案 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)
hashCode
和equals
。例如,您希望能够将它们用作Set
或Map
这是另一个更个人的偏好:
Set
或Map
中,但您只有一个实例并且不需要结构相等,则首选class Foo(val i: Int)
case class Foo(i: Int)
,因为您没有可能进行更昂贵的平等检查。如果1.和2.碰撞,您可以手动实现特定的案例类功能。例如,为可变的非案例类提供伴随apply
方法或模式匹配提取器。
答案 3 :(得分:5)
案例类为您提供“免费”(即,您不必编写)equals
,hashcode
和toString
以及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的列。