scala学习

函数式编程

函数式编程与面向对象编程

  • 面向对象编程:解决问题,分解对象,行为,属性,然后通过对象的关系以及行为的调用来解决问题。
  • 函数式编程:解决问题时,将问题分解成一个一个的步骤,将每个步骤进行封装(函数),通过调用这些封装好的步骤,解决问题。
  • scala即是一个完全面向对象编程语言,也是一个完全函数式编程语言。

函数的基本语法

  • 基本语法:def 函数名(参数:参数类型,……):函数返回类型 = { 函数体 }

  • 函数声明:

        // 无参 无返回值
        def func1() = {
          println("无参 无返回值")
        }
        // 无参 有返回值
        def func2()={
          "无参 有返回值"
        }
        // 有参 无返回值
        def func3(s:String)={
          println(s)
        }
        // 有参 有返回值
        def func4(s:String)={
          s
        }
        // 多参
        def func5(s1:String,s2:String)={
          println(s"s1=$s1,s2=$s2")
        }
    

    在scala中,函数的返回值可以就是其最后一行语句的值,可以忽略return关键字

函数参数

  • scala中的可变参数与带名参数:

    	//可变参数:	
        def func6(s:String*): Unit ={
          println(s)
        }
        func6("hello","world")
        func6()
    	/*
    	 输出结果如下:
    	 WrappedArray(hello, world)
    	 List()
    	*/
    

    当有多个参数的时候,可变参数需要放在最后

        //带名参数
    	def func7(name:String,age:Int = 1): Unit ={
          println(s"name:$name,age:$age")
        }
        func7("ada")
        func7("abis",34)
        func7(age = 23,name = "asdf")
    	/*
    	 输出结果如下:
    	 name:ada,age:1
    	 name:abis,age:34
    	 name:asdf,age:23
    	*/
    

scala中的函数至简原则

所谓函数至简原则,一句话概括则是:能省则省

细节:

  • return可以省略,scala会使用函数体最后一行代码最为返回值
  • 返回值类型如果能够推断出来,则可以省
  • 如果函数体只有一行代码,可以省
  • 如果函数无参,则可以省略小括号,若定义函数时省去小括号,则调用该函数时也需省略小括号,反之,则可省可不省
  • 如果函数明确声明返回Unit,那么在函数中使用return也不起作用
  • scala如果想自动推断无返回值,可以省略等号
  • 如果不关心名称只关心逻辑处理,函数名可以省略
  • 如果函数使用return关键字,那么函数的返回值不能自行推断

高阶函数

  • 参数中带有函数的函数称为高阶函数:

        def sum(x: Int, y: Int): Int = {
          x + y
        }
    
        def dif(x: Int, y: Int): Int = {
          x - y
        }
    
        def func8(x: Int, y: Int, operate: (Int, Int) => Int) = {
          operate(x, y)
        }
    
        println(func8(2, 3, sum))
        println(func8(2, 3, dif))
    	/*
    	 输出结果为:
    	 5
    	 -1
    	*/
    

匿名函数

  • 匿名函数即没有函数名的函数,可以通过函数自变量(拉姆达表达式)来设置匿名函数:

  • 定义格式为:val 函数名:函数类型 = 拉姆达表达式

  • 如:

        val sum: (Int, Int) => Int = (x: Int, y: Int) => x + y
        println(sum(1, 2))
    	/*
    	 输出结果为:
    	 3
    	*/
    

函数的柯里化和闭包

  • 函数柯里化:即将一个接收多个参数的函数转化成一个接受一个参数的函数的过程,可以接单的理解为一种特殊的参数列表声明方式

        val sum = (x: Int, y: Int, z: Int) => x + y + z
        val sum1 = (x:Int)=>{
          y:Int=>{
            z:Int=>{
              x+y+z
            }
          }
        }
        val sum2=(x:Int)=>(y:Int)=>(z:Int)=>x+y+z
        def sum3(x:Int)(y:Int)(z:Int)= x+y+z
    
        println(sum(1, 2, 3))
        println(sum1(1)(2)(3))
        println(sum2(1)(2)(3))
        println(sum3(1)(2)(3))
    	/*
    	 输出结果为:
    	 6
    	 6
    	 6
    	 6
    	*/
    
  • 闭包:即将一个函数与其相关的引用环境(变量)组合成一个整体

        // 变量
        val x = 1
        // 函数闭包:
        def func9(x:Int,y:Int)={
          x+y
        }
    

递归

  • 一个函数在函数体内调用了本身,即称为递归

  • scala中对于一种特殊的递归——尾递归进行了优化

    • 尾递归即函数在函数体最后调用它本身,就被称为尾递归。
    • scala中会直接将尾递归编译成一个循环语句,因此不会出现栈溢出的问题
    	//简单尾递归
        def func10(x:Int,y:Int):Int ={
          if (y<=0) x else func10(x+y,y-1)
        }
        println(func10(0,4))
    	/*
    	 输出结果为:
    	 10
    	*/
    

惰性求值

  • 当函数的返回值被声明为lazy的时候,函数的执行将会被推迟,直到我们首次对此取值,该函数才会执行,这种函数就被称为惰性函数

        def func11() ={
          println("lazy print")
          "lazy return"
        }
        lazy val result = func11()
        println("under lazy result")
        println(s"result=$result")
    	/*
    	 输出结果为:
    	 under lazy result
    	 lazy print
    	 result=lazy return
    	*/
    

    *ps:lazy不能修饰var声明的变量


版权声明:本文为airleaya原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/airleaya/article/details/112272269