文档章节

《programming in scala》2ed chap9学习笔记

谦谦君子
 谦谦君子
发布于 2013/12/30 11:18
字数 613
阅读 19
收藏 0
import java.io.{PrintWriter, File}

/**
 * Created by ly on 13-12-27.
 */
object ControlAbstraction {

  object FileMatcher {
    // 9.1 Reducing code duplication
    private def filesHere = (new File(".")).listFiles

    def fileMatching(query: String, matcher: (String, String) => Boolean) = {
      for (file <- filesHere if matcher(file.getName, query))
      yield file
    }

    def fileEnding_Full(query: String) = fileMatching(query, (fileName: String, query: String) => fileName.endsWith(query))

    // 因为有类型推导,且每个参数按顺序只用了一遍,所以可以用_placeholder
    // 不是closure,因为matcher的两个参数都是bound variable,没有free
    def fileEnding(query: String) = fileMatching(query, _.endsWith(_))

    def fileContaining(query: String) = fileMatching(query, _.contains(_))

    def fileRegex(query: String) = fileMatching(query, _.matches(_))


    // 使用closure避免query参数的传递
    private def fileMatchingClosure(matcher: String => Boolean) = {
      for (file <- filesHere if matcher(file.getName)) yield file
    }

    def fileEndingClosure(query: String) = fileMatchingClosure(_.endsWith(query))

    /*
    9.2 Simplifying client code
    collections types special-purpose looping: List, Set, Map, exists, filter, map
     */

    /*
    9.3 Currying
    A curried function is applied to multiple argument lists, instead of just one.
     */
    def curriedSum(x: Int)(y: Int) = x + y

    def first(x: Int) = (y: Int) => x + y

    val second = first(1)
    val onePlus = curriedSum(1) _
    val result = onePlus(2) // 3

    /*
    9.4 Writing new control structures
    In languages with first-class functions, you can effectively make new control structures even though the syntax of the language is fixed. All you need to
do is create methods that take functions as arguments.
     */
    // loan pattern,可以确保流关闭!
    def withPrintWriter(file: File, op: PrintWriter => Unit) {
      val writer = new PrintWriter(file)
      try {
        op(writer)
      } finally {
        writer.close()
      }
    }

    withPrintWriter(
      new File("date.txt"),
      writer => writer.println(new java.util.Date)
    )
    /*
    One way in which you can make the client code look a bit more like a
built-in control structure is to use curly braces instead of parentheses to sur-
round the argument list. In any method invocation in Scala in which you’re
passing in exactly one argument, you can opt to use curly braces to surround
the argument instead of parentheses.
     */
    println("Hello, kitty!")
    println {
      "Hello, kitty"
    }

    // 但是两个参数不行,因此需要用curried函数
    //"Hello".substring{7, 9}
    def withPrintWriterCurried(file: File)(op: PrintWriter => Unit) {
      val writer = new PrintWriter(file)
      try {
        op(writer)
      } finally {
        writer.close()
      }
    }

    // 用{}更像是native control structure
    withPrintWriterCurried(new File("data.txt")) {
      writer => writer.println(new java.util.Date())
    }

    def withPrintWriterCurried2(op: PrintWriter => Unit)(file: File) {
      val writer = new PrintWriter(file)
      try {
        op(writer)
      } finally {
        writer.close()
      }
    }

    withPrintWriterCurried2 {
      writer => writer.println(new java.util.Date())
    }(new File("."))

    /*
    9.5 By-name parameters
    withPrintWriter第二个参数,还需要传递writer =>...如果不需要参数的话,可以写得更简洁
     */
    var assertionsEnabled = false

    def myAssert(predicate: () => Boolean) =
      if (assertionsEnabled && !predicate())
        throw new AssertionError

    myAssert(() => 5 > 3)

    //myAssert(5 > 3) // Won’t work, because missing () =>

    /*
     byNameAssert参数会在函数调用之后在evaluated,而boolAssert会在函数调用之前先evaluated
     By contrast, because the type of byNameAssert ’s
predicate parameter is => Boolean , the expression inside the parentheses
in byNameAssert(5 > 3) is not evaluated before the call to byNameAssert .
Instead a function value will be created whose apply method will evaluate
5 > 3 , and this function value will be passed to byNameAssert .
     */
    def byNameAssert(predicate: => Boolean) =
      if (assertionsEnabled && !predicate)
        throw new AssertionError

    byNameAssert(5 > 3)
    byNameAssert(1 / 0 == 0)

    // 没有问题

    def boolAssert(predicate: Boolean) =
      if (assertionsEnabled && !predicate)
        throw new AssertionError

    boolAssert(5 > 3)
    boolAssert(1 / 0 == 0) // java.lang.ArithmeticException: / by zero
  }

  def main(args: Array[String]) {

  }

}


© 著作权归作者所有

共有 人打赏支持
谦谦君子
粉丝 37
博文 61
码字总数 56919
作品 0
成都
程序员
私信 提问
《programming in scala》2ed chap13学习笔记

scala的private访问权限 class Outer { class Inner { class InnerMost { f() // OK (new Inner).f } private[Outer] def d() { println("d") } private def f() { println("f") } (new Inne......

谦谦君子
2014/01/13
0
0
《programming in scala》2ed chap15学习笔记

package chap15 sealed abstract class Expr // 加了sealed,其他文件里不能extends Exprcase class Var(name: String) extends Exprcase class Number(num: Double) extends Exprcase clas......

谦谦君子
2014/01/14
0
0
Scala 的学习笔记系列(持续更新中)

最近学习 Scala,因它是灵活的函数式编程,还有就是能为 PlayFramework 2.0 服务,看的是 《Programming in Scala》 那本书,并记下自己认为值得记录的东西,列举 Scala 用元组/列表类型实现...

YanbinQ
2012/10/26
0
1
Spark 学习资源收集

(一)spark 相关安装部署、开发环境 1、Spark 伪分布式 & 全分布式 安装指南 http://my.oschina.net/leejun2005/blog/394928 2、Apache Spark探秘:三种分布式部署方式比较 http://dongxic...

openthings
2016/05/29
164
0
Spark 学习资源收集【Updating】

(一)spark 相关安装部署、开发环境 1、Spark 伪分布式 & 全分布式 安装指南 http://my.oschina.net/leejun2005/blog/394928 2、Apache Spark探秘:三种分布式部署方式比较 http://dongxic...

大数据之路
2014/09/08
0
1

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7 yum 安装git

CentOS7 yum 安装git 1.查看系统是否已经安装git 1 git --version 2.CentOS7 yum 安装git 1 yum install -y git 3.安装成功 4.卸载git 1 yum remove git  ...

linjin200
33分钟前
1
0
vue页面闪现源码的处理方法

1.添加样式 <style type="text/css"> [v-cloak] { display: none; } </style> 2.在app id上添加v-cloak指令 <div class="wrapper wrapper-content " id="app" v-cloak>......

qiang123
37分钟前
2
0
Hyperledger Fabric 实战(十二): Fabric 源码本地调试

借助开发网络调试 fabric 源码本地调试 准备工作 IDE Goland Go 1.9.7 fabric-samples 模块 chaincode-docker-devmode fabric 源码 步骤 添加本地域名 127.0.0.1 peer 127.0.0.1 orderer 用 ...

Jonluo
38分钟前
1
0
自然语言处理hanlp的入门基础

此文整理的基础是建立在hanlp较早版本的基础上的,虽然hanlp的最新1.7版本已经发布,但对于入门来说差别不大!分享一篇比较早的“旧文”给需要的朋友! 安装HanLP HanLP将数据与程序分离,给...

左手的倒影
40分钟前
1
0
KaliLinuxNetHunter教程实施刷机解锁Bootloader

KaliLinuxNetHunter教程实施刷机解锁Bootloader 当用户将前面的工作都准备完成后,即可开始刷机。其中,整个刷机过程分为三个步骤,分别是解锁Bootloader、刷入第三方Recovery和实施刷机。为...

大学霸
41分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部