何时使用案例类或常规类

Vik*_* V. 39 scala

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

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

hel*_*ser 54

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

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


因此,如果出现以下情况,请不要使用Case Classes:

  1. 你的班级有可变状态.
  2. 你的课包括一些逻辑.
  3. 您的类不是数据表示形式,并且您不需要结构相等.

但是,在这些情况下,您应该考虑代码的样式,因为它可能不够功能.


And*_*ann 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 _ => ...
}
Run Code Online (Sandbox Code Playgroud)


0__*_*0__ 10

  1. 当你的类带有可变状态时,不要使用case类.
  2. 当你想要结构相等时,请使用 case类,因为它给你正确的hashCodeequals.例如,您希望能够将它们用作a Set或中的键Map

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

  • 如果你只是想自动干将,你把情况在SetMap,但你永远只能有一个实例,不需要构造平等,更喜欢class Foo(val i: Int)case class Foo(i: Int),因为你没有可能更昂贵的平等检查.

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


小智 6

案例类是以数据为中心的。

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

(1) 值等价:这意味着可以将两个 case 实例与它们内部的值进行比较。

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
Run Code Online (Sandbox Code Playgroud)

但是没有定义其他比较运算符(>、>= < 等)。

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

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

scala> time1.hours
res9: Int = 12
Run Code Online (Sandbox Code Playgroud)

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


Gal*_*Gal 5

案例类为您提供"免费"(即你没有写)的实现equals,hashcodetoString,以及applyunapply在同伴对象.基本上,您可以将案例类视为命名元组,其字段也可以命名.

对于其他任何事情,你可能最好使用普通的课程.