Mak*_*e42 1 scala language-construct syntactic-sugar language-concepts
在
trait Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
object CaseExample {
def eval(e: Expr): Int = e match {
case Number(n) => n
case Sum(e1, e2) => eval(e1) + eval(e2)
}
def main(args: Array[String]) {
println(eval(Sum(Number(1), Number(2)))) //> 3
}
}
Run Code Online (Sandbox Code Playgroud)
还有相当多的语法糖.我得到的case是隐式创建两个对象
object Number extends Expr {
def apply(n: Int) = new Number(n)
}
object Sum extends Expr {
def apply(e1: Expr, e2: Expr) = new Sum(e1, e2)
}
Run Code Online (Sandbox Code Playgroud)
这就是为什么我们可以编写eg Sum(...)并仍然通过类实例化一个对象,因为Sum(...)它也是语法糖Sum.apply(...).
我是对的,match构造也是语法糖?如果是,如何 - 例如case Number(n)- 由编译器重写?
我问,因为我没有看到nin在case Number(n)任何地方定义和/或绑定到一个值.奇怪的是,在一个match构造中,第一个字母的情况很重要(如果它是大写的,它将是一个常数).这很奇怪,因为据我所知,这仅仅是一个match相关的构造,所以我不知道这将如何去糖.
是的,match是语法糖.它会unapply在您的对象上调用该方法.Daniel Westheide有一篇关于它的好文章.
具体来说,当您定义case classfor时Number,这是编译器实际生成的内容:
case class Number(n: scala.Int) extends scala.AnyRef with Expr with scala.Product with scala.Serializable {
val n: scala.Int = { /* compiled code */ }
/* omitted for brevity */
}
object Number extends scala.runtime.AbstractFunction1[scala.Int, Number] with scala.Serializable {
def this() = { /* compiled code */ }
final override def toString(): java.lang.String = { /* compiled code */ }
def apply(n: scala.Int): Number = { /* compiled code */ }
def unapply(x$0: Number): scala.Option[scala.Int] = { /* compiled code */ }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,Number伴随对象附带编译器生成的unapply方法.
您可以在此处找到Scala模式匹配工具设计的详尽说明.
- 编辑 -
如果要查看实际的,编译器生成的代码,请运行scalac -print Number.scala.以下是相关位:
<synthetic> object Number extends scala.runtime.AbstractFunction1 with Serializable {
/* ... */
case <synthetic> def unapply(x$0: Number): Option = if (x$0.==(null))
scala.this.None
else
new Some(scala.Int.box(x$0.n()));
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
如果你编写一个match表达式,你可以类似地运行scalac -print以查看match它本身是如何被贬低的(基本上是:if和else表达式).
| 归档时间: |
|
| 查看次数: |
360 次 |
| 最近记录: |