scala 何时使用案例类或常规类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26118270/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use case class or regular class
提问by Viktor V.
I have some misunderstanding in what cases I should use case class or regular class following by best practices. I have already read about differences of both classes but cannot imagine myself real-life examples where is reccommended to use case or regular class.
我有一些误解在什么情况下我应该按照最佳实践使用案例类或常规类。我已经阅读了这两个类的差异,但无法想象自己在现实生活中推荐用例或常规类的例子。
Could anybody show me real examples with explanation why it's reccommended to do so and not otherwise?
任何人都可以向我展示真实的例子并解释为什么建议这样做而不是其他方式?
回答by hellraiser
If you are going to write purely functional code with immutable objects, you should better try avoidusing regular classes. The main idea of the functional paradigm is the separation of data structures and operations on them. Case Classes are a representation of a data structure with the necessary methods. Functions on the data should be described in different software entities (e.g., traits, objects).
如果您打算使用不可变对象编写纯函数式代码,则最好尽量避免使用常规类。功能范式的主要思想是将数据结构和对它们的操作分离。案例类是具有必要方法的数据结构的表示。数据的功能应该在不同的软件实体(例如特征、对象)中描述。
Regular classes, on the contrary, link data and operations to provide the mutability. This approach is closer to the object-oriented paradigm.
相反,常规类链接数据和操作以提供可变性。这种方法更接近于面向对象的范式。
As a result, do not use Case Classesif:
因此,在以下情况下不要使用案例类:
- Your class carries mutable state.
- Your class includes some logic.
- Your class is not a data representation and you do not require structural equality.
- 你的类带有可变状态。
- 您的课程包含一些逻辑。
- 你的类不是数据表示,你不需要结构相等。
However, in these cases, you should really think about the style of your code because it probably is not functional enough.
但是,在这些情况下,您应该真正考虑代码的风格,因为它可能不够实用。
回答by Andreas Neumann
Case Classesare normal classeswith syntactic sugar. So there is no real big difference, you can do everything with a case class you can do with a class and vice versa.
案例类是带有语法糖的普通类。所以没有什么大的区别,你可以用一个案例类来做任何事情,你可以用一个类来做,反之亦然。
Case classes just save you a lot of boiler plate code to write.
案例类只是为您节省了大量要编写的样板代码。
Perfect fit, as the name suggests, is the use of case classes in pattern matchingwith case.
完美契合,顾名思义,就是在模式匹配中使用 case 类与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 _ => ...
}
回答by 0__
- When your class carries mutable state, do notuse case classes.
- When you want structural equality, do usea case class, as it gives you proper
hashCodeandequals. For example, you want to be able to use them as keys into aSetorMap
- 当您的类带有可变状态时,请不要使用案例类。
- 当您想要结构相等时,请使用case 类,因为它为您提供适当的
hashCode和equals。例如,您希望能够将它们用作进入Set或Map
Here is another more personal preference:
这是另一个更个人的偏好:
- When you simply want the automatic getters, and you put instances in a
SetorMap, but you only ever have one instance and do not require structural equality, preferclass Foo(val i: Int)overcase class Foo(i: Int), because you don't have possibly more expensive equality checks.
- 如果你只是想自动干将,你把情况在
Set或Map,但你永远只能有一个实例,不需要构造平等,更喜欢class Foo(val i: Int)过case class Foo(i: Int),因为你没有可能更昂贵的平等检查。
If 1. and 2. collide, you can implement specific case class features by hand. For example, provide a companion applymethod or a pattern-matching extractor for a mutable non-case class.
如果 1. 和 2. 发生冲突,您可以手动实现特定的案例类特征。例如,为apply可变的非大小写类提供伴随方法或模式匹配提取器。
回答by Gal
A case class gives you "free" (i.e., you don't have to write) implementations of equals, hashcodeand toString, as well as applyand unapplyin the companion object.
Basically, you can think of a case class as a named tuple, whose fields are named as well.
案例类为您提供了“免费”(即,您不必编写)equals,hashcode和toString以及伴随对象中的apply和unapply的实现。基本上,您可以将 case 类视为一个命名的 tuple,其字段也被命名。
For anything else, you're probably better off using a normal class.
对于其他任何事情,您最好使用普通课程。
回答by anshu kumar
case classes are datacentric.
案例类是以数据为中心的。
We get following advantages by using case class over regular classes.
通过使用案例类而不是常规类,我们获得了以下优势。
(1) Value equivalence : It means that two case instances can be compared against values inside them.
(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
But other comparison operators(>, >= <, etc) are not defined.
但是没有定义其他比较运算符(>、>= < 等)。
(2) Immutable Fields: Thread-safe
(2) 不可变字段:线程安全
(3) Automatic field creation: hoursand minutesare immutable fields automatically created by Scala.
(3) 自动创建字段:小时和分钟是Scala自动创建的不可变字段。
scala> time1.hours
res9: Int = 12
case classes are also used in parsing spark DataFrame rows and advantage is that columns of DataFrame can be accessed by field name of case class.
case 类也用于解析 spark DataFrame 行,优点是可以通过 case 类的字段名称访问 DataFrame 的列。
回答by roterl
Normal classes are classes as classes in Java. It can contain both state and functionality.
Case classes are like data POJO in Java. classes that hold state, which can be used by functions (usually in other classes).
普通类是作为 Java 中的类的类。它可以包含状态和功能。
Case 类就像 Java 中的数据 POJO。保存状态的类,可以被函数使用(通常在其他类中)。
When you are implementing data POJO in Java you should set the variable it hold, add getter and setter for them, implement hashcode and equals, and probably implement toString.
Usually it's not that bad since after defining the variables, the IDE can generate all for you, but if you change/add variables then you should remember to update all the methods.
in case classes you define the variables (or better values) and the compiler generate all the methods for you. So you gain both, no boilerplate and updated functionality.
For case classes the compiler also generate more functionality, that you don't and can't have in Java, the copy function and apply/unapply in the companion object.
当你在 Java 中实现数据 POJO 时,你应该设置它保存的变量,为它们添加 getter 和 setter,实现 hashcode 和 equals,并可能实现 toString。
通常情况并没有那么糟糕,因为在定义变量之后,IDE 可以为您生成所有内容,但是如果您更改/添加变量,那么您应该记住更新所有方法。
万一您定义了变量(或更好的值)并且编译器为您生成所有方法。因此,您可以获得两者,没有样板文件和更新的功能。
对于 case 类,编译器还会生成更多的功能,您在 Java 中没有也不能拥有,复制功能和伴随对象中的应用/取消应用。

