理解 Scala 中的 Case 类和特征 [英] Understanding Case class and Traits in Scala

查看:56
本文介绍了理解 Scala 中的 Case 类和特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的特征,定义如下:

I have a simple trait as defined below:

trait MyTrait {

  def myStringVal: String

}

我实现这个特性的案例类如下:

My case class which implements this trait is as below:

case class MyCaseClass(myStringVal: String) extends MyTrait {
  ...
  ...
}

来自 Java 世界,我发现很难理解 MyCaseClass 实际上只是通过为 MyCaseClass 定义一个参数来实现这一点的事实.我知道你的字节码实际上会编写 getter 和 setter.但是,如果没有任何 var 或 val,这怎么可能呢?

Coming from a Java world, I find it a bit difficult to fathom the fact that MyCaseClass actually implements this just by defining a parameter to MyCaseClass. I understand that thy byte code would actually write the getter and setter. But how is this possible without any var or val?

我的理解是,如果没有var或者val,那么就没有生成getter或者setter方法.在那种情况下,上面的案例类 MyCaseClass 是如何实现 myStringVal 方法的?

My understanding is that if there is no var or val, then there is no getter or setter method generated. In that case how is the above case class MyCaseClass implementing myStringVal method?

有时太多的 Scala 魔法难以理解,尤其是对于遗留代码.

Sometime too much of this Scala magic is difficult to understand especially with legacy code.

推荐答案

您可能想查看 这篇博客文章介绍了案例类到底是什么以及它们为何如此有用.

You might want to check out this blog article covering what case classes exactly are and why they are so useful.

在您的示例中,特征 MyTrait 没有用,除了能够像 java 接口一样运行.请注意,Scala 中的默认可见性是公开的.默认情况下,case 类参数是不可变的,因此在您的示例中 val 由编译器自动推断为 myStringVal 参数.

In your example, the trait MyTrait has no use, except being able to function like a java interface. Note, that the default visibility in scala is public. By default case class parameters are immutable so in your example val is automatically inferred by the compiler for the myStringVal argument.

案例类有什么魔法?!

  • 默认字段将所有构造函数参数转换为公共只读(val)
  • 使用每个方法的所有构造函数参数生成toString()equals()hashcode()方法
  • 生成具有相同名称的伴生对象,其中包含适当的 apply()unapply() 方法,它们基本上只是一个方便的构造函数,允许在不使用 new 关键字和一个提取器,默认情况下它会生成一个选项包装的 tuple 案例类参数.
  • Convert all constructor parameters to public readonly (val) by default fields
  • Generate the toString(), equals() and hashcode() methods using all constructor params for each method
  • Generate companion object with the same name containing an appropriate apply() and unapply() method, which are basically just a convenience constructor allowing to instantiate without using the new keyword and an extractor which by default generates an option-wrapped tuple of the case class parameters.

(案例)类的示例编译器输出(复制自 scalatutorial.de)

Sample compiler output for (case) classes (copied from scalatutorial.de)

一个简单的Scala类定义,如

A simple scala class definition like

class A1(v1: Int, v2: Double)

被编译成java代码

public class A1 extends java.lang.Object implements scala.ScalaObject {
  public A1(int, double);
}    

类似的案例类

case class A2(v1: Int, v2: Double)

被编译为以下 java 类

gets compiled to the following java classes

public class A2 extends java.lang.Object implements 
scala.ScalaObject,scala.Product,java.io.Serializable {
  public static final scala.Function1 tupled();
  public static final scala.Function1 curry();
  public static final scala.Function1 curried();
  public scala.collection.Iterator productIterator();
  public scala.collection.Iterator productElements();
  public double copy$default$2();
  public int copy$default$1();
  public int v1();
  public double v2();
  public A2 copy(int, double);
  public int hashCode();
  public java.lang.String toString();
  public boolean equals(java.lang.Object);
  public java.lang.String productPrefix();
  public int productArity();
  public java.lang.Object productElement(int);
  public boolean canEqual(java.lang.Object);
  public A2(int, double);
}


public final class A2$ extends scala.runtime.AbstractFunction2 
implements scala.ScalaObject {
  public static final A2$ MODULE$;
  public static {};
  public scala.Option unapply(A2);
  public A2 apply(int, double);
  public java.lang.Object apply(java.lang.Object, java.lang.Object);
}   

这篇关于理解 Scala 中的 Case 类和特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆