zoukankan      html  css  js  c++  java
  • scala:把函数作为值或参数进行传递、作为返回值进行返回,以及什么是闭包和柯里化

    @

    函数可以作为值进行传递

    • 语法var f = 函数名 _
    • 如果明确了变量的数据类型,那么下划线可以省略
    //函数正常的声明与调用
        def foo():Int={
          println("foo...")
          10
        }
        //将foo函数的执行结果赋值给res变量
        //val res: Int = foo()
        //println(res)
    
        //函数作为值进行传递  语法:在函数名称的后面  +  空格  加下划线
        //注意:将foo函数作为一个整体,赋值给f变量,  f是函数类型 ()=>Int
        //val f : () => Int = foo _
        def f : () => Int = foo _
    
    
        //这个时候,f就是一个函数,如果要想运行f函数的话,必须得加()
        //println(f)   //<function0>
        //println("-----------------")
        //println(f())
    
        //var ff = foo   //将函数执行结果赋值给ff
        //var ff = foo _   //将函数本身作为值赋给ff
    
        //将函数本身作为值赋给ff    如果明确了变量的类型,那么空格和下划线可以省略
        //var ff:()=>Unit = foo
        //println(ff)
    

    函数可以作为参数进行传递

    • 通过匿名函数
    • 扩展函数的功能
    • 提高函数的灵活度
      //函数可以作为参数,进行传递(大多数情况都是通过匿名函数的形式)
        //定义一个函数calculator,该函数接收一个函数类型的参数op,op定义了对两个整数要进行什么样的操作
        def calculator(a:Int,b:Int,op:(Int,Int)=>Int): Int ={
          op(a,b)
        }
    
        //定义一个函数f1,完成两个整数的加法运算
        def op(a:Int,b:Int):Int={
          a + b
        }
        //println(calculator(10,20,op))
        println(calculator(50, 20, (a: Int, b: Int) => {
          a - b
        }))
    
        println(calculator(50, 20, _ - _))
        println(calculator(50, 20, _ + _))
        */
    

    函数可以作为返回值进行返回

    • 函数的嵌套
    • 函数链式调用,通过参数传递数据,在执行的过程中,函数始终占据栈内存,容易导致内存溢出
    //函数可以作为返回值进行返回----函数的嵌套
        def f1():()=>Unit ={
          def f2(): Unit ={
            println("f2函数被调用了")
          }
          //将f2作为返回值返回给f1
          f2 _
        }
    
        //ff就是f2
        //var ff = f1()
        //ff()
    
        //f1()()
    

    闭包

    内层函数访问外层函数的局部变量,会自动延长外层函数局部变量的生命周期,与内层函数形成一个闭合的效果,我们称之为闭包

    /*
        def f1(): (Int)=>Int ={
          var a:Int = 10
          def f2(b:Int): Int ={
            a + b
          }
          f2 _
        }
        */
    
        //执行f1函数返回f2,将返回的f2赋值给ff变量
        //val ff: Int => Int = f1()
    
        //闭包:内存函数f2要访问外层函数f1局部变量a,当外层函数f1执行结束之后,f1会释放栈内存,但是会自动的延长f1函数的局部变量的生命周期,
        //    和内层函数f2形成一个闭合的效果,我们将这种闭合的效果称之为闭包
    
        //如果存在闭包,那么编译器会生成包含$anonfun$的字节码文件
    
        //闭包  = 外层函数的局部变量  + 内层函数
    
        //调用ff函数,其实就是调用f2
        //println(ff(20))
    
        //也可以直接通过如下方式调用
        //println(f1()(30))
    
    
        println("-----------------------------------")
        //以上代码可以转换为如下代码
        /*
        def f3() ={
          var a:Int = 10
          (b:Int) => a + b
        }
    
        f3()(30)
        */
    

    柯里化

    • 将一个参数列表中的多个参数,拆分为多个参数列表
    • 好处1:每一个参数列表表示函数清晰明确
    • 好处2:简化闭包代码的编写
    //柯里化
        //将一个函数的一个参数列表中的多个参数,拆分为多个参数列表
        //简化闭包代码的编写
        def f4()(b:Int):Int = {
          var a:Int = 10
          a + b
        }
        println(f4()(20))
    
        //f4在执行的时候,其实会转换为以下结构
        /*
        def f4() ={
          var a:Int = 10
          (b:Int) => a + b
        }
    

    什么是匿名函数

    • 参数的类型可以省略,会根据形参进行自动的推导
    • 类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参数超过1的永远不能省略圆括号。
    • 匿名函数如果只有一行,则大括号也可以省略
    • 如果参数只出现一次,则参数省略且后面参数可以用_代替
    如果真的不知道做什么 那就做好眼前的事情吧 你所希望的事情都会慢慢实现...
  • 相关阅读:
    Python 批量修改图片格式和尺寸
    c++ placement new概念
    xcopy
    STL List::sort() 解析
    程序猿的骄傲,以及骄傲背后真实的原因。
    误人子弟的网络,谈谈HTTP协议中的短轮询、长轮询、长连接和短连接
    【niubi-job——一个分布式的任务调度框架】----niubi-job这下更牛逼了!
    程序员面经:面试前到底该不该刷题以及面试前该如何准备
    送给即将毕业的同学,谈谈毕业后第一份工作和追女生的问题。
    一个最新发现,原来程序员的最终归宿在这里。
  • 原文地址:https://www.cnblogs.com/sunbr/p/14431715.html
Copyright © 2011-2022 走看看