Scala函数式编程

函数式编程

面向对象编程

分解对象,行为,属性,然后通过对象的关系以及行为的调用来解决问题

函数式编程

将问题分解成一个一个的步骤,将每个步骤进行封装(函数),通过调用这些封装好的功能按照指定的步骤,解决问题。

基础函数编程

基本语法
[修饰符] def 函数名 ( 参数列表 ) [:返回值类型] = {
    函数体
}

private def test( s : String ) : Unit = {
    println(s)
}
函数&方法
  • scala 中存在方法与函数两个不同的概念,二者在语义上的区别很小。scala 方法是类的一部分,而函数是一个对象,可以赋值给一个变量。换句话来说在类中定义的函数即是方法。scala 中的方法跟 Java 的类似,方法是组成类的一部分。scala 中的函数则是一个完整的对象。
  • Scala中的方法和函数从语法概念上来讲,一般不好区分,所以简单的理解就是:方法也是函数。只不过类中声明的函数称之为方法,其他场合声明的就是函数了。类中的方法是有重载和重写的。而函数可就没有重载和重写的概念了,但是函数可以嵌套声明使用,方法就没有这个能力了,千万记得哟。
函数定义

1)无参,无返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun1(): Unit = {
            println("函数体")
        }
        fun1()
    }
}

2)无参,有返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun2(): String = {
            "zhangsan"
        }
        println( fun2() )
    }
}

3)有参,无返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun3( name:String ): Unit = {
            println( name )
        }
        fun3("zhangsan")
    }
}

4)有参,有返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun4(name:String): String = {
            "Hello " + name
        }
        println( fun4("zhangsan") )
    }
}

5)多参,无返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun5(hello:String, name:String): Unit = {
            println( hello + " " + name )
        }
        fun5("Hello", "zhangsan")
    }
}

6)多参,有返回值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun6(hello:String, name:String): String = {
            hello + " " + name
        }
        println( fun6("Hello", "zhangsan"))
    }
}
函数参数

1)可变参数

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun7(names:String*): Unit = {
            println(names)
        }
        fun7()
        fun7( "zhangsan" )
        fun7( "zhangsan", "lisi" )
    }
}

可变参数不能放置在参数列表的前面,一般放置在参数列表的最后

oobject ScalaFunction {
    def main(args: Array[String]): Unit = {
        // Error
        //def fun77(names:String*, name:String): Unit = {
            
        //}
        def fun777( name:String, names:String* ): Unit = {
            println( name )
            println( names )
        }
    }
}

2)参数默认值

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun8( name:String, password:String = "000000" ): Unit = {
            println( name + "," + password )
        }
        fun8("zhangsan", "123123")
        fun8("zhangsan")
    }
}

3)带名参数

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun9( password:String = "000000", name:String ): Unit = {
            println( name + "," + password )
        }
        fun9("123123", "zhangsan" )
        fun9(name="zhangsan")
    }
}
函数至简原则

所谓的至简原则,其实就是Scala的作者为了开发人员能够大幅度提高开发效率。通过编译器的动态判定功能,帮助我们将函数声明中能简化的地方全部都进行了简化。也就是说将函数声明中那些能省的地方全部都省掉。所以这里的至简原则,简单来说就是:能省则省。
1)省略return关键字

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun1(): String = {
            return "zhangsan"
        }
        def fun11(): String = {
            "zhangsan"
        }
    }
}

2)省略花括号

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun2(): String = "zhangsan"
    }
}

3)省略返回值类型

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun3() = "zhangsan"
    }
}

4)省略参数列表

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun4 = "zhangsan"
    }
}

5)省略等号
如果函数体中有明确的return语句,那么返回值类型不能省略

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun5(): String = {
            return "zhangsan"
        }
        println(fun5())
    }
}

如果函数体返回值类型明确为Unit, 那么函数体中即使有return关键字也不起作用

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun5(): Unit = {
            return "zhangsan"
        }
        println(fun5())
    }
}

如果函数体返回值类型声明为Unit, 但是又想省略,那么此时就必须连同等号一起省略

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun5() {
            return "zhangsan"
        }
        println(fun5())
    }
}

6)省略名称和关键字

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        () => {
            println("zhangsan")
        }
    }
}

高阶函数编程

函数作为值
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun1(): String = {
            "zhangsan"
        }
        val a = fun1
        val b = fun1 _
        println(a)
        println(b)
    }
}
object Scala06_Function {
  def main(args: Array[String]): Unit = {
    // TODO Scala 函数式编程 - 函数作为值

    def test(name:String):String ={
      "name =" + name
    }

    def test1(): Unit ={
      println("test1.....")
    }

    def test3(name:String,age:Int) :Unit ={
      println("name = " + name +" , age = "+ age )
    }
    //test1

    // 将函数赋值给变量
    // 1. 如果希望将函数对象赋值给变量,需要通过 (函数名 _ )  来进行赋值
    val fun1 = test _
    println(fun1("zhangsan"))



    //2. 如果不想使用下划线将函数赋值给某个变量.

    val fun2 : String => String   = test

    println(fun2("lisi"))


    val fun3: (String,Int)=>Unit  = test3

    val fun4 = test3 _
  }
}



函数作为参数
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun2( i:Int ): Int = {
            i * 2
        }
        def fun22( f : Int => Int ): Int = {
            f(10)
        }
        println(fun22(fun2))
    }
}
object Scala07_Function {
  def main(args: Array[String]): Unit = {
    // TODO Scala 函数式编程 - 函数作为参数
    // 函数是一个对象. 有具体的类型.
    def test(): Unit ={
      println("Hello test.....")
    }

    def fun(f:()=>Unit): Unit ={
        f()
    }

   // fun(test)


    def test1(name:String):String={
      "name = " + name
    }

    def fun1(f:String=>String,name:String):String={
      f(name)
    }

    println(fun1(test1, "zhangsan"))




  }
}

函数作为返回值
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun3( i:Int ): Int = {
            i * 2
        }
        def fun33( ) = {
            fun3 _
        }
        println(fun33()(10))
    }
}
object Scala10_Function {
  def main(args: Array[String]): Unit = {
   // TODO Scala 函数式编程 - 函数作为返回值

    def test(name:String):String ={
      "name = "+ name
    }

    //val b = test _
    //val bb : String => String = test
    def fun() ={

      test _
    }

    def fun1():String =>String  ={

      test
    }

    // 调用
    println(fun()("zhangsan"))


    // TODO 2. 嵌套函数

    // 外部函数
    def fun2():String => String = {

      // 内部函数
      def test2(name:String):String={
        "name = " + name
      }

      test2 _
    }

  }

}
匿名函数
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun4( f:Int => Int ): Int = {
            f(10)
        }
        println(fun4((x:Int)=>{x * 20}))
        println(fun4((x)=>{x * 20}))
        println(fun4((x)=>x * 20))
        println(fun4(x=>x * 20))
        println(fun4(_ * 20))
    }
}
object Scala08_Function {
  def main(args: Array[String]): Unit = {
    // TODO Scala 函数式编程 - 函数作为参数 - 匿名函数
    // 函数是一个对象. 有具体的类型.
    // 通常情况下, 函数作为参数使用时,都会使用匿名函数
    // 至简原则:
    // 1. 如果匿名函数的函数体只有一行语句,{} 可以省略
    // 2. 如果匿名函数的参数的类型可以推断,参数类型可以省略.
    // 3. 如果匿名函数的参数只有一个,()可以省略。
    // 4. 如果匿名函数的参数在函数体中只使用一次,参数 和 =>同时省略. 使用 _ 代替参数.


    def fun(f:String => String):String={
      f("zhangsan")
    }

    def test(name :String):String={
      name * 2
    }

    //fun(test)
    println(fun((name: String) => {
      println("haha")
      name * 2
    }
    ))

    println(fun((name: String) => name * 2))

    println(fun((name) => name * 2))

    println(fun(name => name * 2))

    println(fun( _ * 2))





    // 实现一个计算的功能.  可能计算的功能有: + - * /

    def cal(f:(Int,Int)=>Int,x:Int,y:Int):Int={
      f(x,y)
    }


    println(cal((i: Int, j: Int) => {i + j}, 10, 20))
    println(cal((i, j) => {i + j}, 10, 20))
    println(cal( {_ + _} , 10, 20))
  }
}
闭包
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun5() = {
            val i = 20
            def fun55() = {
                i * 2
            }
            fun55 _
        }
        fun5()()
    }
}
object Scala11_Function {
  def main(args: Array[String]): Unit = {
   // TODO Scala 函数式编程 - 嵌套函数 - 闭包
   // 内部函数使用了外部的变量,  而外部的变量在外部函数执行完后就已经没有作用域了.
   // 但是内部函数能正常使用到外部函数的外部变量, 因为编译器修改了内部函数的参数列表。
    // 将外部的变量作为内部函数的参数传递到了内部的函数.
   // 把这个现象就称之为闭包

   // 这只是闭包的一种现象.
   // 其实闭包还有别的表现: 匿名函数就是闭包现象  将函数作为值赋值给变量也是闭包想象  嵌套函数中内部函数在外部使用也是闭包现象.
   // 当前的版本(2.12) :
   // 早期的版本(2.11) : 如果有闭包现象,编译后会多出一个匿名类。

  // Spark :  Spark如何判断是否闭包现象



   def fun1(i:Int):Int=>Int ={

     def fun2(j:Int):Int={
       i + j
     }

     fun2 _
   }

    println(fun1(1)(2))  // 调用完fun1()拿到返回值后  ->   调用fun2()



   // TODO 匿名函数
    /*
   def test(f:String => String):Unit={
     println(f("zhangsan"))
   }

   test(_ * 2 )



     */

  // TODO 将函数赋值给变量
  /*
  def test(): Unit ={

  }

  val b = test _
 */

  // TODO 嵌套函数的内部函数在外部使用
  /*
  def test(): ()=>Unit ={

    def test1(): Unit ={

    }

    test1 _



  }
*/


  }


}

函数柯里化
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun6(i:Int)(j:Int) = {
            i * j
        }
    }
}
object Scala12_Function {
  def main(args: Array[String]): Unit = {
   // TODO  Scala 函数式编程 - 柯里化
   // 所谓的函数柯里化,实际上就是支持写多个参数列表
   // 也有一个好处就是能够简化复杂的参数列表

   def test (i:Int ): Unit  ={
     def test1(j:Int): Unit ={
       println(i + j )
     }

     test1(10)
   }

    test(20)


   def fun(i:Int,m:Int)(j:Int): Unit ={
      println(i + j )
   }

    def fun1(i:Int)(j:Int)(f:(Int,Int)=>Int): Int ={
      f(i,j)
    }

    println(fun1(1)(2)(_ + _))
  }

}
控制抽象
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun7(op: => Unit) = {
            op
        }
        fun7{
            println("xx")
        }
    }
}
object Scala13_Function {
  def main(args: Array[String]): Unit = {
   // TODO  Scala 函数式编程 - 控制抽象
   // 从1 循环到 5 ,当循环到3的时候,跳出循环
    Breaks.breakable{

      for(i <- 1 to 5 ){
        if(i == 3){
          Breaks.break()
        }
        println("i = " + i)
      }

    }

    println("xxxxxxxx")



    def my(op: =>String){
       println("my 开始......")
       println(op)
       println("my 结束......")
    }


   // my(println(123))

    my{
      val age  =20
      if(age < 20){
        //println("少年")
        "少年"
      }else{
        //println("打工者...")
        "打工的"
      }

    }

  }

}
递归函数
object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun8(j:Int):Int = {
            if ( j <= 1 ) {
                1
            } else {
                j * fun8(j-1)
            }
        }
        println(fun8(5))
    }
}
object Scala14_Function {
  def main(args: Array[String]): Unit = {
   // TODO  Scala 函数式编程 - 递归函数
   // 递归: 自己调用自己
   // 注意: 1. 递归一定要有退出的条件
   //      2.  在scala中递归的方法需要明确声明返回值类型

   // 例子:  5 + 4 + 3 + 2 + 1

   /*
   // 发散性递归
   def sum(num:Int):Int={
      if(num <=1){
        1
      }else{
        num + sum(num - 1 )
      }
   }

  //  println(sum(5))

    println(sum(1000000000))   //java.lang.StackOverflowError

  */


   def fun(): Unit ={
     println()
     fun()
   }


   // 尾递归

    // 5 , 0  => sum(4, 5)
    // 4 , 5  => sum(3, 9 = 5 + 4 )
    // 3 , 9  => sum(2,12 = 5 + 4 + 3 )
    // 2 ,12  => sum(1,14 = 5 + 4 + 3 + 2 )
    // 1 ,14  => sum(0,15 = 5 + 4 + 3 + 2 + 1)
    // 0 ,15  => 15

    def sum(num:Int,result:Int):Int={

      if(num < 1 ){
         result
      }else{

        sum(num-1,  num + result  )

      }
    }

    println(sum(100000000, 0))


  }

}

惰性函数

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

object ScalaFunction {
    def main(args: Array[String]): Unit = {
        def fun9(): String = {
            println("function...")
            "zhangsan"
        }
        lazy val a = fun9()
        println("----------")
        println(a)
    }
}
object Scala15_Function {
  def main(args: Array[String]): Unit = {
   // TODO  Scala 函数式编程 - 惰性函数 lazy

   def test ():String={
     println("test......")
     "zhangsan"
   }

   lazy val username = test()

   println("xxxxxxxxxxxxxxxxxxxxxxxxxx")

   println("username :" + username)


  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值