概述:

case类在模式匹配和actor中经常使用到,当一个类被定义成为case类后,Scala会自动帮你创建一个伴生对象并帮你实现了一系列方法且带来了不少好处,如下:

1.实现了apply方法,意味着你不需要使用new关键字就能创建该类对象
  1. scala> case class People(name:String,age:Int)
  2. defined class People
  3.  
  4. scala> val p = People("mobin",22) //省略了new关键字
  5. p: People = People(mobin,22)

  

2.实现了unapply方法,可以通过模式匹配来获取类属性,是Scala中抽取器的实现和模式匹配的关键方法。
  1. scala> p match { case People(x,y) => println(x,y) }
  2. (mobin,22)

 

3.实现了类构造参数的getter方法(构造参数默认被声明为val),但是当你构造参数是声明为var类型的,它将帮你实现setter和getter方法(不建议将构造参数声明为var)

 
构造参数为val的情况(默认):
  1. scala> p.name
  2. res0: String = mobin
  3.  
  4. scala> p.name = "mobin1" //报错,因为构造参数被声明为val所以并没有帮你实现setter方法
  5. <console>:10: error: reassignment to val
  6. p.name = "mobin1"
 
构造参数为var的情况:
  1. scala> case class People(var name:String) //参数被声明为var
  2. defined class People
  3.  
  4. scala> val p = People("mobin")
  5. p: People = People(mobin)
  6.  
  7. scala> p.name = "mobin2"
  8. p.name: String = mobin2
  9.  
  10. scala> p.name
  11. res1: String = mobin2 //修改成功,并没有报错

  

4.还默认帮你实现了toString,equals,copy和hashCode等方法
 
详述:
我们再通过反编译来看看当你定义一个case类时编译器是怎么做的:
同样定义一个简单的case类:
Person.scala
  1. case class Person(name: String,age : Int)

  

通过终端中编译该文件(scalac Person.scala)后生成两个class文件,Person.class和Person$.class
 
接下来再通过javap Person命令反编译Person.class,结果结果如下:
  1. Compiled from "Person.scala"
  2. public class com.mobin.scala.Person implements scala.Product,scala.Serializable {
  3. public static scala.Function1<scala.Tuple2<java.lang.String, java.lang.Object>, com.mobin.scala.Person> tupled();
  4. public static scala.Function1<java.lang.String, scala.Function1<java.lang.Object, com.mobin.scala.Person>> curried();
  5. public java.lang.String name();
  6. public int age();
  7. public com.mobin.scala.Person copy(java.lang.String, int);
  8. public java.lang.String copy$default$1();
  9. public int copy$default$2();
  10. public java.lang.String productPrefix();
  11. public int productArity();
  12. public java.lang.Object productElement(int);
  13. public scala.collection.Iterator<java.lang.Object> productIterator();
  14. public boolean canEqual(java.lang.Object);
  15. public int hashCode();
  16. public java.lang.String toString();
  17. public boolean equals(java.lang.Object);
  18. public com.mobin.scala.Person(java.lang.String, int);
  19. }
 
再反编译Person$.class
  1. Compiled from "Person.scala"
  2. public final class com.mobin.scala.Person$ extends scala.runtime.AbstractFunction2<java.lang.String, java.lang.Object, com.mobin.scala.Person> implements scala.Serializable {
  3. public static final com.mobin.scala.Person$ MODULE$;
  4. public static {};
  5. public final java.lang.String toString();
  6. public com.mobin.scala.Person apply(java.lang.String, int);
  7. public scala.Option<scala.Tuple2<java.lang.String, java.lang.Object>> unapply(com.mobin.scala.Person);
  8. public java.lang.Object apply(java.lang.Object, java.lang.Object);
  9. }
 
通过反编译以上两个class文件可以知道,当你将一个类定义为case类后,编译器就自动帮你实现了一系列方法。
 
我们再来对比下去掉case关键字将类定义为普通类后反编译的结果
  1. class Person(var name : String,var age : Int) //将参数声明为var

  

反编译的结果如下:
  1. Compiled from "Person.scala"
  2. public class com.mobin.scala.Person {
  3. public java.lang.String name();
  4. public void name_$eq(java.lang.String);
  5. public int age();
  6. public void age_$eq(int);
  7. public com.mobin.scala.Person(java.lang.String, int);
  8. }

  

比较之下case类比普通的类多了不少的方法,所以当你不需要这些额外的方法时你就可以将类定义为普通的类,但是你又不想通过new关键字来创建实例,你可以在普通类中实现apply方法达到此目的。
 
因为case本就旨在创建的是不可变数据,所以在使用模式匹配时显得极为容易
 

Scala--样例类(case)详解的更多相关文章

  1. WPF 后台任务 等待动画 样例 && C# BackgroundWorker 详解

    运行效果: 前台代码: <Window x :Class="Waiting.Window1" xmlns="http://schemas.microsoft.com ...

  2. 28.C++- 单例类模板(详解)

    单例类 描述 指在整个系统生命期中,一个类最多只能有一个实例(instance)存在,使得该实例的唯一性(实例是指一个对象指针)  , 比如:统计在线人数 在单例类里,又分为了懒汉式和饿汉式,它们的区 ...

  3. scala 样例类

    一.case class 的特征 package com.jason.qianfeng case class Message(sender: String, receiver: String, bod ...

  4. 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型

    一.前述 Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大. 模式匹配机制相当于java中的switch-case. 使用了case关键字的类定义就是样例类(case ...

  5. Scala基础:模式匹配和样例类

    模式匹配 package com.zy.scala import scala.util.Random /** * 模式匹配 */ object CaseDemo { def main(args: Ar ...

  6. 学好Spark/Kafka必须要掌握的Scala技术点(二)类、单例/伴生对象、继承和trait,模式匹配、样例类(case class)

    3. 类.对象.继承和trait 3.1 类 3.1.1 类的定义 Scala中,可以在类中定义类.以在函数中定义函数.可以在类中定义object:可以在函数中定义类,类成员的缺省访问级别是:publ ...

  7. Scala模式匹配和样例类

    Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配. 1.字符匹配     def mai ...

  8. Scala学习十四——模式匹配和样例类

    一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...

  9. Scala集合库、模式匹配和样例类

    package com.yz8 import org.junit.Test class test { @Test def test: Unit = { val ints = List(1,5,7,6, ...

随机推荐

  1. .NET 面试题(1)

    1.简述 private. protected. public. internal 修饰符的访问权限. private:私有成员,在类的内部才能访问 protected:保护成员,在该类内部和继承本类 ...

  2. AFNetwork 作用和使用方法具体解释

    转自:http://www.maxiaoguo.com/clothes/269.html AFNetworking是一个轻量级的iOS网络通信类库.它建立在NSURLConnection和NSOper ...

  3. Lua内存泄漏应对方法[转]

    转自http://blog.csdn.net/xocoder/article/details/42685685 由于目前正在负责的项目是一个二次开发项目,而且留给我们的代码质量实在让人无力吐槽,所以遇 ...

  4. PHP获取中英文混合字符串长度及截取

    1.字符串长度 PHP获取中英文混合字符串长度的实现代码如下,1中文=1位,2英文=1位,可自行修改 /** * PHP获取字符串中英文混合长度 * @param $str string 字符串 *  ...

  5. SQL语句中的DQL、DML、DCL、DDL、CCL、TPL

    结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统:同时也是数据库 ...

  6. String和StringBuilder 的使用区别

    String 类有不可变性,每次执行操作时都会创建一个新的String对像,需要对该对象分配新的空间. StringBuilder 解决了对字符串重复修改过程中创建大量对象的问题.初始化一个Strin ...

  7. MongoDB学习笔记06

    在shell中删除一个集合,执行db.test.drop()或者db.runCommand({"drop":"test"}),在MongoDB中命令其实是作为一 ...

  8. 1203.1——条件语句 之 if语句

    用if语句可以构成分支结构.它根据给定的条件进行判断,以决定执行某个分支程序段.C语言的if语句有三种基本形式. 语句的三种形式 1) 第一种形式为基本形式:if        if(表达式) 语句其 ...

  9. C# 操作系统防火墙

    很多时候,我们的程序是通过网络通信(如TCP或者UDP协议+端口),而将制作好的程序安装包给客户用时,发现会出现不能通信的现象(或者在这台电脑是可以的,却在另一台不可以),原因是防火墙阻止了,需要添加 ...

  10. add monitor resolution

    cvt 1920 1080 # Get the correct settings for the new mode # Output for me: "1920x1080_60.00&quo ...