0704-Scala函数式编程高级

1. 偏函数

1.1 问题引入

给你一个集合val list = List(1, 2, 3, 4, “abc”) ,请完成如下要求:

  1. 将集合list中的所有数字+1,并返回一个新的集合
  2. 要求忽略掉 非数字 的元素,即返回的 新的集合 形式为 (2, 3, 4, 5)
  1. 解决方式一
    val list = List(1,2,3,4,"abc")

    def f1(n : Any): Boolean = {
        n.isInstanceOf[Int]
    }
    def f2(n : Any): Int = {
        n.asInstanceOf[Int]
    }
    def f3(n: Int) : Int = {
        n + 1
    }
    list.filter(f1).map(f2).map(f3)
  1. 解决方式二: 模式匹配
    val list = List(1,2,3,4,"abc")
    
    def addOne(i : Any): Any = {
        i match {
            case x : Int => x + 1
            case _ =>
        }
    }
    list.map(addOne)
  1. 使用偏函数
    val list1: List[Int] = list.collect {
        case i: Int => i + 1
    }

1.2 偏函数

  1. 对符合某个条件,而不是所有情况进行逻辑操作时,使用偏函数是一个不错的选择
  2. 将包在大括号内的一组case语句封装为函数,我们称之为偏函数,它只对会作用于指定类型的参数或指定范围值的参数实施计算,超出范围的值会忽略.
  3. 偏函数在Scala中是一个特质PartialFunction

2. 作为参数的函数

3. 闭包

3.1 闭包入门

  1. 基本介绍:闭包就是一个函数和与其相关的引用环境(变量/值)组合的一个整体(实体)。
def minusxy(x: Int) = (y: Int) => x – y
//minusxy 他会返回一个匿名函数 (y: Int) => x – y
//匿名函数,他使用了一个外部的变量 x
//f函数就是闭包.
val f: Int => Int = minusxy(20)
println("f(1)=" + f(1)) 
println("f(2)=" + f(2))
  1. 代码小结
    (1) (y: Int) => x – y
    返回的是一个匿名函数 ,因为该函数引用到到函数外的 x,那么 该函数和x整体形成一个闭包
    如:这里 val f = minusxy(20) 的f函数就是闭包
    (2) 可以这样理解,返回函数是一个对象,而x就是该对象的一个字段,他们共同形成一个闭包
    (3) 当多次调用f时(可以理解多次调用闭包),发现使用的是同一个x, 所以x不变。
    (4)在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为他们会组合成一个整体(实体),形成一个闭包

3.2 闭包案例

请编写一个程序,具体要求如下

  1. 编写一个函数 makeSuffix(suffix: String) 可以接收一个文件后缀名(比如.jpg),并返回一个闭包
  2. 调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg) ,则返回 文件名.jpg , 如果已经有.jpg后缀,则返回原文件名。
  3. 要求使用闭包的方式完成
  4. String.endsWith(xx)
    def makeSuffix(suffix: String): String => String = {
        (filename : String)=> {
            if (filename.endsWith(suffix)){
                filename
            }else{
                filename + suffix
            }
        }
    }

    val file: String => String = makeSuffix(".jpg")
    
    val filename: String = file("jdj")
    val filename2: String = file("xxx.jpg")

3.3 闭包的优势

  1. 返回的匿名函数和 makeSuffix (suffix string) 的 suffix 变量 组合成一个闭包,因为返回的函数引用到suffix这个变量
  2. 体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入后缀名,比如 .jpg ,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把

4. 柯里化

编写一个函数,接收两个整数,可以返回两个数的乘积,要求:

  1. 使用常规的方式完成
  2. 使用闭包的方式完成
  3. 使用函数柯里化完成
def mul(x: Int, y: Int) = x * y
println(mul(10, 10))

def mulCurry(x: Int) = (y: Int) => x * y
println(mulCurry(10)(9))

def mulCurry2(x: Int)(y:Int) = x * y
println(mulCurry2(10)(8))
// 将接受多个参数的函数都可以转化为接受单个参数的函数,这个转化过程就叫柯里化

5. 控制抽象

可以理解为传递的是一段逻辑, 一段代码

  1. 参数是函数
  2. 函数参数没有输入值也没有返回值 () => Unit
    def myRunInThread(f1: () => Unit) = {
        new Thread {
            override def run(): Unit = {
                f1()
            }
        }.start()
    }

    myRunInThread {
        () =>
            println("干活咯!5秒完成...")
            Thread.sleep(5000)
            println("干完咯!")
    }
	// 省略括号
    def myRunInThread(f1: => Unit) = {
        new Thread {
            override def run(): Unit = {
                f1()
            }
        }.start()
    }

    myRunInThread {
        println("干活咯!5秒完成...")
        Thread.sleep(5000)
        println("干完咯!")
    }
    var x = 10
    def until(condition: => Boolean)(block: => Unit): Unit = {
        //类似while循环,递归
        if (condition) {
            block
            until(condition)(block)
        }
    }
    until(x > 0) {
        x -= 1
        println("x=" + x)
    }
    // 可以理解为: 参数有多行改用{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值