Scala空类,对象,特征

时间:2017-05-25 06:06:44

标签: scala

我想学习斯卡拉语 在许多文档或视频教程中,我看到scala开发人员创建了空类或对象,并将其作为参数用于另一个类或实现空特征! 例如:

object Controller {
  sealed trait Controller
  case object Login extends Controller
  case object Logout extends Controller
}

或者这个:

sealed trait Expression
case class Number(num: Int) extends Expression
case class Plus(a: Expression, b: Expression) extends Expression
case class Minus(a: Expression, b: Expression) extends Expression

object ExpressionEvaluate {
  def value(expression: Expression): Int = expression match {
    case Number(value) => value
    case Plus(a, b) => value(a) + value(b)
    case Minus(a, b) => value(a) - value(b)
  }
}

我想知道这种模式是什么? 什么是空类,对象或特征? 为什么开发人员使用这种模式?

1 个答案:

答案 0 :(得分:6)

这种模式:

sealed trait Controller
case object Login extends Controller
case object Logout extends Controller

或者这个

sealed trait Expression
case class Number(num: Int) extends Expression
case class Plus(a: Expression, b: Expression) extends Expression
case class Minus(a: Expression, b: Expression) extends Expression

被称为algebraic data types。它们是Scala创建co-product/sum types(也称为标记联合)的方式。当您在签名中收到类型为Expression的特征时,您知道您将收到一个具体的实现。您发现哪种类型是具体类型的方式是通过pattern matching,这是匹配类型的能力。更重要的是,编译器足够智能,sealed trait知道其所有底层具体类型,并告知您模式匹配并非详尽无遗,例如,如果我添加Divide类型:

case class Divide(a: Expression, b: Expression) extends Expression

编译时,编译器会抱怨:

Warning:(18, 48) match may not be exhaustive.
It would fail on the following input: Divide(_, _)
      def value(expression: Expression): Int = expression match {

至于“空类”,我们必须区分两种类型。一个是case class。案例类是一种在Scala中创建不可变记录类型的方法,将它们视为类固醇上的product type。这些类是编译器自动派生hashCodeequals的实现的类,并且还添加了在我们通过apply / unapply模式匹配时为我们提供语法糖的方法。例如:

case Number(value) => value

您看到我们能够在模式匹配中访问value上的Number字段,这怎么可能?这是可能的,因为编译器为我们提供了一个unapply方法,用于解构案例类。

另一个是case object,这是一种在Scala中创建singleton type(一种只代表一个值的类型)的方法。由于我们在LoginLogout上没有任何字段,因此我们可以创建该类型的单个表示。