`
fineqtbull
  • 浏览: 51218 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Scala学习笔记(Scala编程第15章 Case Classes and Pattern Matching 例子分析)

阅读更多
《Programming In Scala》第15章 Case Classes and Pattern Matching 例子

源程序:
/**
 * 《Programming In Scala》第15章 Case Classes and Pattern Matching 例子
 */
package org.stairwaybook.expr
import layout.Element.elem
import layout.Element

//表达式基类
sealed abstract class Expr
//变量
case class Var(name: String) extends Expr
//数字
case class Number(num: Double) extends Expr
//一元操作符表达式
case class UnOp(operator: String, arg: Expr) extends Expr
//两元操作符表达式
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
class ExprFormatter {
    // 以升序定义操作符的优先级,同一Set内的元素为同一优先级
    private val opGroups =
        Array(
        Set("|", "||"),
        Set("&", "&&"),
        Set("ˆ"),
        Set("==", "!="),
        Set("<", "<=", ">", ">="),
        Set("+", ""),
        Set("*", "%")
    )
    // 生成操作符优先级Map,Map项目为操作符及它所在的索引号
    private val precedence = {
        val assocs =
            for {
                i <- 0 until opGroups.length
                op <- opGroups(i)
            } yield op -> i
        Map() ++ assocs
    }
    //一元操作符的优先级最高
    private val unaryPrecedence = opGroups.length
    //由于除法操作符使用竖向排版所以给予特殊优先级
    private val fractionPrecedence = -1

    private def format(e: Expr, enclPrec: Int): Element =
        e match {
            //变量
            case Var(name) =>
                elem(name)
            //数字
            case Number(num) =>
                def stripDot(s: String) =
                    if (s endsWith ".0") s.substring(0, s.length - 2)
                    else s
                elem(stripDot(num.toString))
            //一元操作符
            case UnOp(op, arg) =>
                elem(op) beside format(arg, unaryPrecedence)
            //除法竖向排版
            case BinOp("/", left, right) =>
                //被除数
                val top = format(left, fractionPrecedence)
                //除数
                val bot = format(right, fractionPrecedence)
                //中间的横线
                val line = elem('-', top.width max bot.width, 1)
                //三部分合并
                val frac = top above line above bot
                //前一操作符不是/
                if (enclPrec != fractionPrecedence) frac
                //前一操作符是/,则两边加空格防止与两边的操作符相连
                else elem(" ") beside frac beside elem(" ")
            //两元操作符
            case BinOp(op, left, right) =>
                //优先级
                val opPrec = precedence(op)
                //左边操作数
                val l = format(left, opPrec)
                //右边操作数
                val r = format(right, opPrec + 1)
                //横向排版
                val oper = l beside elem(" "+ op +" ") beside r
                //前一操作符优先级 <= 本操作符优先级
                if (enclPrec <= opPrec) oper
                //前一操作符优先级 > 本操作符优先级, 打破了优先级默认规则所以加()
                else elem("(") beside oper beside elem(")")
        }
    //使用默认优先级(0)来格式化。
    def format(e: Expr): Element = format(e, 0)
}
//文件主单例对象,作为本文件的主执行程序
object Express extends Application {
    val f = new ExprFormatter
    // 1 / 2 * (x + 1)
    val e1 = BinOp("*", BinOp("/", Number(1), Number(2)),
                        BinOp("+", Var("x"), Number(1)))
    // (x / 2) + (1.5 / x)
    val e2 = BinOp("+", BinOp("/", Var("x"), Number(2)),
                        BinOp("/", Number(1.5), Var("x")))
    // e1 / e2
    val e3 = BinOp("/", e1, e2)
    //定义打印函数
    def show(e: Expr) = println(f.format(e)+ "\n\n")
    //打印每一元素
    for (val e <- Array(e1, e2, e3)) show(e)
}


执行结果:
1          
- * (x + 1)
2          


x   1.5
- + ---
2    x 


1          
- * (x + 1)
2          
-----------
  x   1.5  
  - + ---  
  2    x   
0
0
分享到:
评论

相关推荐

    Scala学习笔记,大全笔记

    Scala学习笔记,大全笔记

    Scala学习笔记(全)

    ### Scala学习笔记(全) #### 一、Scala概述与特点 Scala是一种多范式的编程语言,旨在集成面向对象编程和函数式编程的各种特性。它运行于Java平台(Java虚拟机JVM),并且能够完全兼容所有的Java程序。这使得Scala...

    scala学习笔记整理

    在"scala学习笔记整理"中,我们可以深入探讨以下关键知识点: 1. **基础语法**:Scala的基础语法与Java有相似之处,但也有很多独特的特点。例如,它支持变量的不可变性(immutability),使用`val`声明常量,`var`...

    scala编程中文pdf

    scala编程 33章 中文pdf Scala编程实战 目录 第1章字符串. 11 第2章数值39 第3章控制结构.60 第4章类和属性.103 第5章方法147 第6章对象170 第7章包和导入.190 第8章特质200 第9章函数式编程214 第10 章集合242 第...

    Scala学习笔记

    ### Scala学习笔记关键知识点 ...以上内容涵盖了Scala学习笔记中的关键知识点,从并发编程到函数式编程的核心概念,再到Scala语言本身的一些特殊规则和特点,这些都是学习Scala时需要掌握的基础知识。

    Scala编程 pdf

    Scala编程是一种多范式、函数式和面向对象的编程语言,设计目的是为了提高开发者的生产力,同时保持代码的可维护性和高性能。它是由Martin Odersky在2003年设计并实现的,融合了Java虚拟机(JVM)的优势,并引入了...

    Scala和Spark大数据分析函数式编程、数据流和机器学习

    Scala是一种静态类型的函数式编程语言,而Spark是一个分布式计算框架,尤其适合于大数据处理和分析。本教程将深入探讨这两者如何结合,实现高效的大数据分析、数据流处理以及机器学习任务。 首先,让我们来理解...

    快学Scala完整版&Scala编程(中文版)&Scala程序设计-多线程编程实践

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,使得它在处理并发和大数据分析方面尤为出色。这个压缩包包含了三本关于Scala学习的重要资源,分别是《快学Scala》完整版书籍、《SCALA程序...

    Scala函数式编程

    《Scala函数式编程》是针对希望学习FP并将它应用于日常编码中的程序员而写的,内容包括:函数式编程的概念;函数式编程相关的各种“为什么”和“怎么做”;如何编写多核程序;练习和检测。 从OOP到FP,思路的转化 ...

    scala学习资料

    Scala是一种强大的、现代的编程语言,它融合了面向对象编程(OOP)和函数式编程(FP)的特性,为开发者提供了丰富的表达能力和高效的代码执行环境。作为Java平台上的一个成员,Scala程序可以在Java虚拟机(JVM)上...

    scala学习笔记1

    ScalaOverview.pdf ScalaTutorial.pdf ProgrammingInScala.pdf(这本是书) 博文链接:https://dogstar.iteye.com/blog/182673

    Scala编程例子

    Scala编程例子 Scala是一种强大的、多范式的编程语言,它结合了面向对象和函数式编程的概念,为开发者提供了丰富的表达性和灵活性。对于初学者来说,理解Scala的基本语法和特性是至关重要的,因为这将帮助他们更好...

    [Scala学习笔记-中文资料]从java角度看Scala

    [Scala学习笔记-中文资料] 从java角度看Scala

    最好的scala学习 课件

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,被广泛应用于大数据处理领域,特别是与Apache Spark相结合时。本课件是针对Scala学习者精心准备的资源,旨在帮助你深入理解和掌握Scala的...

    scala核心编程总结

    6. **Pattern Matching(模式匹配)**:Scala的模式匹配功能强大,不仅可以用于匹配简单的值,还能应用于类型匹配、抽象语法树等复杂场景。这种能力大大简化了代码的编写,提高了代码的可读性。 7. **Object ...

    读书笔记:scala 编程代码实际例子.zip

    读书笔记:scala 编程代码实际例子

    读书笔记:Scala编程学习.zip

    读书笔记:Scala编程学习

Global site tag (gtag.js) - Google Analytics