美文网首页
essential scala: Case Classes与模式

essential scala: Case Classes与模式

作者: 周一不上班 | 来源:发表于2018-05-02 16:24 被阅读28次

Case Class不仅定义了一个类,而且同时创建一个伴生对象,并且默认拥有诸多特性,提供了一种简便的创建类的方式。如果你的类中成员没有那么复杂时,case class是理想的类创建方式。

使用关键字case初始化一个类。

case class Person(firstName: String, lastName: String) {
def name = firstName + " " + lastName
}

scala会自动创建一个类和一个伴生对象。

val dave = new Person("Dave", "Gurnell") // we have a class
    // dave: Person = Person(Dave,Gurnell)
Person // and a companion object too
    // res: Person.type = Person

同时,scala会预先赋予case class诸多特性。

特性

  1. 构造参数自动成为类成员
dave.firstName
// res: String = Dave
  1. 默认toString方法返回构造函数样式
dave
// res: Person = Person("Dave","Gurnell")
  1. equals hashCode方法通过成员变量进行计算。

以上特性使得case class在集合类,如List,Map,Set中,方便使用。同时意味着我们可以通过比较成员变量来确定两个对象的等价性,而不是通过对比引用地址。

new Person("Noel", "Welsh").equals(new Person("Noel", "Welsh"))
  // res: Boolean = true
new Person("Noel", "Welsh") == new Person("Noel", "Welsh")
  // res: Boolean = true
  1. copy方法返回一个全新的引用(对象),成员变量完全相同。
dave.copy()
  // res2: Person = Person(Dave,Gurnell)
dave.copy() eq res0
// res: Boolean = false

实际上copy方法接受可选的构造参数,如果参数被指定,复制的全新对象中的成员变量的值是指定的而不是从原来的对象中复制来的。这样允许我们在复制的时候修改某些成员变量的值。

dave.copy(firstName = "Dave2")
// res: Person = Person(Dave2,Gurnell)
  1. 实现了Serializable

等价性(值还是引用)

Scala== 操作符和Java的不同,Scala==等同于equals,而不是Java中对比引用。

Scalaeq操作符等同于Java中的==

new Person("Noel", "Welsh") eq (new Person("Noel", "Welsh"))
  // res: Boolean = false
dave eq dave
  // res: Boolean = true

伴生对象特性

伴生对象有一个和类构造函数一模一样参数列表的apply方法。这样可以不使用new关键字来创建对象。

Person("Dave", "Gurnell") == Person("Noel", "Welsh")
// res: Boolean = false
Person("Dave", "Gurnell") == Person("Dave", "Gurnell")
// res: Boolean = true

Case object

如果想定义一个没有初始化参数的case class,可以直接使用case object。并且拥有和case class一样的默认函数(equals hashCode toString等)。

case object Citizen {
  def firstName = "John"
  def lastName = "Doe"
  def name = firstName + " " + lastName
}

case object定义了一个类和对象,并且这个对象是这个类的唯一实例。

class Citizen { /* ... */ }
object Citizen extends Citizen { /* ... */ }

case object和case class拥有同样的功能特性。

模式匹配

以上,我们可以通过方法调用或者成员访问与对象进行交互,同样,我们可以通过另外一种方式--模式匹配。

模式匹配像是一个扩展的if表达式,通过“形状”来辨识对象。

case class Person(firstName: String, lastName: String)

“形状”蕴含在构造函数里。

现在我们想找出星球大战中的反抗军成员。

object Stormtrooper {
  def inspect(person: Person): String =
    person match {
      case Person("Luke", "Skywalker") => "Stop, rebel scum!"
      case Person("Han", "Solo") => "Stop, rebel scum!"
      case Person(first, _) => s"Move along, $first"
    }
}

note: _匹配所有值,并忽略它。

使用

Stormtrooper.inspect(Person("Noel", "Welsh"))
// res: String = Move along, Noel
Stormtrooper.inspect(Person("Han", "Solo"))
// res: String = Stop, rebel scum!

实现二叉树(int)

abstract class IntTree
case object EmptyTree extends IntTree
case class TreeNode(value: Int, left: IntTree, right: IntTree) extends IntTree

def contains(e: Int, t: IntTree): Boolean = t match {
  case EmptyTree => false
  case TreeNode(v, left, right) => if (v == e) true else contains(e, left) || contains(e, right)
} 

def insert(e: Int, t: IntTree): Unit = t match {
  ???
}

scala> contains(1, TreeNode(2, TreeNode(1, EmptyTree, EmptyTree), EmptyTree))
// res0: Boolean = true

当然你也可以加入泛型以支持任何类型的元素。

abstract class BTree[A]
case object EmptyTree extends BTree
case class TreeNode[A](value: A, left: BTree[A], right: BTree[A]) extends BTree[A]

相关文章

  • essential scala: Case Classes与模式

    Case Class不仅定义了一个类,而且同时创建一个伴生对象,并且默认拥有诸多特性,提供了一种简便的创建类的方式...

  • case class

    Case Classes Scala 支持 case classes 记法。Case Class 就是普通的类, ...

  • scala 模式匹配

    scala的模式匹配与java的switch case相似,但是switch case只能对值进行判断,scala...

  • case语句与偏函数(转)

    Scala通过case语句提供了形式简单、功能强大的模式匹配功能。但是也许你不知道,Scala还具有一个与case...

  • Scala:样例类(case classes)

    1.概念理解 使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。实现了类构造...

  • Scala学习笔记 A2/L1篇 - 模式匹配和样例类 Patt

    教材:快学Scala chapter 14. 模式匹配和样例类 Pattern Matching and Case...

  • Scala 关于样例类的优点

    case class在匹配模式和actor中经常使用到,当一个类被定义成为case类后,Scala会自动帮你创建一...

  • scala-模式匹配和样例类

    模式匹配和样例类 模式匹配 Scala没有Java中的switch case,它有一个更加强大的模式匹配机制,可以...

  • Essential Scala: Literals

    Scala对象系统 总体上,Scala对象系统可分为两类: 引用类型 值类型 引用类型 AnyRef的子类 使用n...

  • Essential Scala: Bounds

    上界 隐式参数 可以提供「隐式参数」,改善smaller的设计。 当T为Int 编译器实际调用: 其中Orderi...

网友评论

      本文标题:essential scala: Case Classes与模式

      本文链接:https://www.haomeiwen.com/subject/cmkcrftx.html