将所有类定义为Scala中的情况,只是让所有参数自动生成属性是否正确?

Iva*_*van 8 scala case-class

我开始Scala了.我是否正确理解我应该将类定义为案例类,如果我想将它作为属性公开的参数?它不引入任何副作用吗?

Ran*_*ulz 14

为case类生成的样板代码在字节码中的成本很小但非零.除了copy方法,存在hashCode,equalstoString以及伴随对象工厂方法.

更重要的是,从案例类派生类是不可取的.从案例类派生案例类确实会引发问题(编译器会对你大喊大叫).特别是,copy(...)编译器不会生成重写方法,因此如果您尝试复制从案例类派生的案例类,则可以获得一些奇怪的失败模式.

如果你把你的案例类放在任何继承图的叶子上,你会没事的.


den*_*ips 12

您将获得所定义的任何参数的适当性,它们将是vals(即决赛)

case class User(name: String, group: String)
val user = User("jsmith", "admins")

// access both properties
println("name: %s group: %s".format(user.name, user.group))
Run Code Online (Sandbox Code Playgroud)

您也可以使用常规(即非案例类)获得此行为:

// creates two final public properties as well
class User(val name: String, val group: String)

// creates read/write public properties
class User(var name: String, var group: String)
val user = new User("jsmith", "admins")
user.group = "guests"
Run Code Online (Sandbox Code Playgroud)

Case类还带来了很多其他的东西,比如有用的equality,hashcode和toString实现,以及一个带有工厂方法的伴随对象,它不需要使用new等.

正如您所看到的,一个案例类不需要实现您想要的东西,但它可以让您快速到达目的地.至于副作用,定义一个case类会在幕后生成一些代码,以便为您提供上一段中描述的内容.这些通常是有用的,我不会担心它们,但了解它们是很好的.


Lan*_*dei 7

除了已经提到的要点之外,案例类在概念上接近于您在Java中称为"值类"的情况.当然,没有什么可以阻止你编写可变的案例类或具有大量功能但数据很少的案例类,但这可能会让其他人使用你的代码感到惊讶.根据经验,我要说在创建案例类之前至少要三思而后行......

  • 这需要可变的状态
  • 当你不确定以后是否需要子类时
  • 如果他们的主要目的是计算事物(不代表事物),这些计算很复杂
  • 如果您需要对其行为进行细粒度控制(例如,您需要自定义模式匹配)
  • 当表现非常重要时
  • 当你只需要一个"case class feature"时,例如我考虑使用case类只是为了避免在构造函数args前输入"val"作为overkill