美文网首页
scala控制抽象

scala控制抽象

作者: 平头哥2 | 来源:发表于2020-05-04 14:09 被阅读0次

控制抽象

1. 减少代码重复

object FunDemo {

  private val filesHere = new java.io.File(".").listFiles()

  //1.  查询后缀名为 .scala的文件
  def fileEndWith(query: String): Array[File] = {
    for (file <- filesHere; if file.getName().endsWith(query))
      yield file
  }

  //2. 查询文件名包含 phb 的文件
  def fileContains(query: String): Array[File] = {
    for (file <- filesHere; if file.getName().contains(query))
      yield file
  }

  //3. 查询文件名 符合正则表达式的名字
  def fileRegex(query: String): Array[File] = {
    for (file <- filesHere; if file.getName().matches(query))
      yield file
  }

  //4. 前三个方法重复, 使用高阶函数抽象
  def fileMatch(query: String, matcher: (String, String) => Boolean): Array[File] = {
    for (file <- filesHere; if matcher(file.getName, query))
      yield file
  }

  //重构前三个方法
  def fileEndWith2(query: String): Array[File] = {
    fileMatch(query, _.endsWith(_)) //这里使用的不是闭包,就是占位符

    //函数字面量 :_.endsWith(_)  等同于
    //(filename: String, query: String) => filename.endsWith(query)
  }

  def fileContains2(query: String): Array[File] = {
    fileMatch(query, _.contains(_))
  }

  def fileRegex2(query: String): Array[File] = {
    fileMatch(query, _.matches(_))
  }

  //5. 进一步简化代码
  private def fileMatch2(matcher: String => Boolean): Array[File] = {
    for (file <- filesHere; if matcher(file.getName()))
      yield file
  }

  //进一步重构前三个方法
  def fileEndWith3(query: String): Array[File] = {
    fileMatch2(_.endsWith(query)) //这里使用是闭包,自由变量为query
  }

  def fileContains3(query: String): Array[File] = {
    fileMatch2(_.contains(query))
  }

  def fileRegex3(query: String): Array[File] = {
    fileMatch2(_.matches(query))
  }

  def main(args: Array[String]): Unit = {
    //高阶函数: 那些接收函数作为参数的函数
  }
}
object FunDemo {

  private val arr = List(-11, -10, -5, 0, 5, 10)


  def containNeg(nums: List[Int]): Boolean ={

    var exists = false
    for (elem <- nums) {
      if(elem < 0)
        exists = true
    }
    exists
  }

  def containPositive(nums: List[Int]): Boolean ={

    var exists = false
    for (elem <- nums) {
      if(elem > 0)
        exists = true
    }
    exists
  }

  def containOdd(nums: List[Int]): Boolean ={

    var exists = false
    for (elem <- nums) {
      if(elem %2 == 1)
        exists = true
    }
    exists
  }

  def containEven(nums: List[Int]): Boolean ={

    var exists = false
    for (elem <- nums) {
      if(elem %2 == 0)
        exists = true
    }
    exists
  }
}


//----------简化之后如下----------
object FunDemo {
  
  private val arr = List(-11, -10, -5, 0, 5, 10)


  def containNeg(nums: List[Int]): Boolean = {
    contain(nums, _ < 0)
  }

  def containPositive(nums: List[Int]): Boolean = {
    contain(nums, _ > 0)
  }

  def containOdd(nums: List[Int]): Boolean = {
    contain(nums, _ / 2 == 1)
  }

  def containEven(nums: List[Int]): Boolean = {
    //val matcher = (ele: Int) => (ele/2 == 0)
    //contain(nums, matcher)
    //contain(nums, (ele: Int) => (ele / 2 == 0))
    //contain(nums, ele => ele / 2 == 0)
    contain(nums, _ / 2 == 0)
  }

  def contain(nums: List[Int], matcher: Int => Boolean): Boolean = {

    var exists = false
    for (elem <- nums) {
      if (matcher(elem))
        exists = true
    }
    exists
  }
    
  def containNeg2(nums: List[Int]): Boolean = contain(nums, _ < 0)
  def containPositive2(nums: List[Int]): Boolean = contain(nums, _ > 0)
  def containOdd2(nums: List[Int]): Boolean = contain(nums, _ / 2 == 1)
  def containEven2(nums: List[Int]): Boolean = contain(nums, _ / 2 == 0)
}

//-------------集合本省的迭代------------------
object FunDemo {
  def containNeg(nums: List[Int]): Boolean = nums.exists(_ < 0)
  def containPositive(nums: List[Int]): Boolean = nums.exists(_ > 0)
  def containOdd(nums: List[Int]): Boolean = nums.exists(_ % 2 == 0)
  def containEven(nums: List[Int]): Boolean = nums.exists(_ % 2 == 1)
}
//柯里化和普通函数
object FunDemo {
  def sum(a: Int, b: Int) = a + b
  def curriedSum(a: Int)(b: Int) = a + b
  def main(args: Array[String]): Unit = {
    /**
     * 这里调用 柯里化函数
     * 实际上连着做了两次传统的函数调用
     */
    val intToInt = curriedSum(1)(2)
    println(intToInt)

    //1. 获取柯里化函数第一次调用的函数值, 使用占位符
    val one = curriedSum(1)_
    println(one(3))
  }
}
//编写新的控制结构
def twice(op: Double => Double, x: Double): Double = op(op(x))
def main(args: Array[String]): Unit = {
  val op = (x: Double) => x + 5
  println(twice(op, 2))
  println(twice((x: Double) => x + 5, 2))
  println(twice(x => x + 5, 2))
  println(twice(_ + 5, 2)) // 调用
}

//控制抽象
def withPrintWriter(file: File, op: PrintWriter => Unit): Unit = {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}
def main(args: Array[String]): Unit = {
    //调用
  withPrintWriter(new File("data.txt"), out => out.println(new java.util.Date()))
    
  println {
      "aaa"
  } //花括号替代圆括号,看起来更像是内嵌的控制结构
}


//使用柯里化改造
def withPrintWriter(file: File)(op: PrintWriter => Unit): Unit = {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

//调用
def main(args: Array[String]): Unit = {

  val op = (out: PrintWriter) => out.println(new java.util.Date())
  withPrintWriter(new File("data.txt")){
    op
  }

  withPrintWriter(new File("data.txt")){
      //在花括号中编写函数字面量
    out => out.println(new java.util.Date())
  }
}
//传名参数
def main(args: Array[String]): Unit = {
  myAssert(() => 5 > 3) //调用方式很奇怪
}

var assert = true

def myAssert(predicate: () => Boolean): Unit = {
  if (assert && !predicate())
    throw new AssertionError
}

//修改为传名参数:
//定义格式:=> Boolean 
def main(args: Array[String]): Unit = {
  myAssert(5 > 3) //调用方式很奇怪
}

var assert = true

def myAssert(predicate: => Boolean): Unit = {
  if (assert && !predicate)
    throw new AssertionError
}
/**
 * def myAssert(predicate: => Boolean): Unit
 * 和
 * def myAssert2(predicate: Boolean): Unit 区别:
 *
 * myAssert2: 先计算predicate,再做函数调用
 * myAssert:predicate: => Boolean 先转换为一个函数值,调用函数值的apply方法,计算表达式的值,然后再函数调用
 *
 */
def myAssert(predicate: => Boolean): Unit = {
  if (assert && !predicate)
    throw new AssertionError
}

def myAssert2(predicate: Boolean): Unit = {
  if (assert && !predicate)
    throw new AssertionError
}

def main(args: Array[String]): Unit = {
  myAssert(5>3) //不会报错
  myAssert2(2/0==0) // 报错
}

相关文章

  • scala控制抽象

    控制抽象 1. 减少代码重复

  • Scala的控制抽象

    高阶函数(Higher-order Functions) Scala 的控制抽象是根据高阶函数来进行的。高阶函数就...

  • Scala读书笔记

    《Scala编程完整版》笔记 点滴 第9章 控制抽象 scala的任何方法调用,如果只传入一个参数,就能可选地使用...

  • 8. 高阶函数练习

    柯里化: 控制抽象:比如我们自己定义一个until功能: Scala programmers can build ...

  • 控制抽象

    根据正交设计的基本原则,如果设计出现重复的控制逻辑,可抽象出稳定的抽象;借助于Scala强大的可扩展能力,可以将「...

  • 美颜Java

    从原生的Java API创建线程谈起,讲述Scala对「控制结构」抽象的设计与实现. 创建线程 在Java8之前,...

  • scala 抽象类(abstract)与特质(trait)

    抽象类 In Scala, an abstract class is constructed using the ...

  • Scala-简明速学01-控制语句

    Scala-简明速学01-控制语句 while循环 Scala中的while循环基本与Java相似,但是Scala...

  • Scala 的抽象成员

    Key Words: abstract member, pre-initialized fields, lazy ...

  • scala(十) 抽象类和单例对象

    java中的抽象类 语法: [访问修饰符] abstract class 类名{} scala 中的抽象类 语法:...

网友评论

      本文标题:scala控制抽象

      本文链接:https://www.haomeiwen.com/subject/oiaeghtx.html