【问题标题】:Scala empty class,object,traitsScala 空类、对象、特征
【发布时间】:2017-10-25 16:29:07
【问题描述】:

我想学习 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)
  }
}

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

【问题讨论】:

    标签: scala


    【解决方案1】:

    这种模式:

    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。它们是创建co-product/sum types(也称为标记联合)的Scala 方式。当您在签名中收到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
    

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

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

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 1970-01-01
      • 2011-11-19
      • 2018-03-21
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多