zoukankan      html  css  js  c++  java
  • scala(二)

    scala

    函数式编程

    1.基本语法

    [修饰符] def 函数名 ( 参数列表 ) [:返回值类型] = {
        函数体
    }
    private def test( s : String ) : Unit = {
        println(s)
    }
    

    2.函数定义

    无返回值,调用函数后不用print;有返回值,调用函数需要print

    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"))
        }
    }
    

    3.函数参数

    3.1可变参数 (数据类型后面加*)

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

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

    3.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")
        }
    }
    

    如果使name和password交换参数的位置,就没有办法使用默认参数值,故引入带名参数

    3.2带名参数

    参数传递一般是顺序传递,增加参数的名称,用于改变传参的顺序

    object Function02 {
      def main(args: Array[String]): Unit = {
        def fun1(name: String ="lisi",password:String): Unit ={
          println(name + password)
        }
    
        fun1(password = "123313")
      }
    
    }
    

    4.函数至简原则

    能省就省

    4.1省略return关键字

    函数体 会将满足条件的最后一行代码的执行结果作为函数的返回值

    object Function02 {
      def main(args: Array[String]): Unit = {
       def fun1(): String={
            "za"
       }
    
        println(fun1())
      }
    
    }
    

    4.2省略花括号

    如果函数体中的逻辑代码只有一行,那么花括号可以省略

    object Function02 {
      def main(args: Array[String]): Unit = {
       def fun1(): String= "za"
       
    
        println(fun1())
      }
    
    }
    

    4.3省略返回值类型

    如果函数返回数据可以推断出返回值类型的话,返回值类型可以省略

    object Function02 {
      def main(args: Array[String]): Unit = {
       def fun1()="za"
       
    
        println(fun1())
      }
    
    }
    

    4.4省略参数列表

    如果参数列表中没有声明任何的参数,那么参数列表可以省略,但省略之后,调用时也不能加参数列表了

    object Function02 {
      def main(args: Array[String]): Unit = {
       def fun1="za"
       
    
        println(fun1)
      }
    
    }
    

    4.5省略等号 一般返回值类型为unit时省略

    如果函数体中有明确的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())
        }
    }
    

    4.6省略名称和关键字

    省略的同时也需要将返回值类型同时省略,将等号增加一个箭头 匿名函数不能独立使用

    object Function02 {
      def main(args: Array[String]): Unit = {
      def fun1(): String ={
        "xiaobu"
      }
      }
    
    }
    object Function02 {
      def main(args: Array[String]): Unit = {
      ()=>{
          "xiaobu"
      }
      }
    
    }
    

    5高阶函数编程

    所谓的高阶函数,其实就是将函数当成一个类型来使用,而不是当成特定的语法结构

    5.1函数作为值

    如果将函数作为整体,而不是将执行结果赋值给变量,那么需要采用特殊符号:下划线

    之所以使用下划线让函数作为对象使用,因为代码中没有明确变量的类型,所以需要通过取值类推断

    如果变量声明的类型为函数类型,那么可以不适用下划线让函数作为对象

    object Function02 {
      def main(args: Array[String]): Unit = {
    
        def fun1(): String ={
          "zahnsgan"
        }
       val a = fun1()
        println(a)                   //zahnsgan
        println("````````")
        def fun2(): Unit ={
          println("lisi")
        }
        val b = fun2()              //lisi
        println(b)                  // ()
        println("````````")
        def fun3(): Unit ={
          println("zhangsan")
        }
        val c = fun3 _            //将函数对象传给c
        c()                       //()调用函数
      }
    
    }
       val c :() = > unit = fun3  这里可以省略_
    

    5.2函数作为参数(通常会使用匿名函数)

    将函数作为参数传入到函数中,记得传入参数时需去掉()即 传入函数类型的值 fun _ 或者 fun(因为知道传入的类型为函数类型,所以可以省略_)

    不去掉()的话会直接执行 会将执行结果作为参数传入

    如果参数在使用的时候,按照顺序只使用了一次,那么可以使用下划线代替参数

    object Function02 {
      def main(args: Array[String]): Unit = {
    
      def test(f:() => Unit): Unit ={
        f()
      }
        def fun1(): Unit ={
          println("11111")
        }
      test(fun1)
        println("****************")
        def test1(f : (Int,Int) => Int): Unit ={
          val i = f(10,20)
          println(i)
        }
    
        def fun2(x :Int,y: Int): Int ={
          x + y
        }
        test1(fun2)
        println("****************")
        def test2(f : (Int,Int) => Int): Int ={
          f(10,20)
    
        }
    
        def fun3(x :Int,y: Int): Int ={
          x + y
        }
        test1(fun3)
    println("****************")
       test1(
        (x :Int,y: Int) => x + y
     
    )
    匿名函数,传入的函数名称不重要,如果只有一个参数的话可以省略,显然这里不合适
    如果参数在使用的时候,按照顺序只使用了一次,那么可以使用下划线代替参数
    test1(_ + _)
    
    }
    }
    object Function03 {
      def main(args: Array[String]): Unit = {
       def test(x:Int,y:Int,f:(Int,Int)=>Int): Unit ={
         println(f(x, y))
       }
      test(10,20,_ + _)
      }
    }
    
    
    

    5.3匿名函数

    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))          //参数使用时,按照顺序只使用了一次,那么可以使用下划线代替参数
        }
    }
    

    5.4函数作为返回值

    一般使用于内部的函数在外部使用

    object Function04 {
      def main(args: Array[String]): Unit = {
       def outer() ={
         def inner(): Unit ={
           println("inner")
         }
         inner _
       }
        outer()()
      }
    
    }
    

    5.5闭包

    一个函数使用了外部的变量,把这个变量包含到了它的内部来使用,改变了这个变量的生命周期

    将当前的代码形成了一个闭合的环境,这个环境称之为闭包环境,简称为闭包

    1.内部函数在外部使用的时候会有闭包2.将函数作为对象使用会有闭包3.所有的匿名函数都有闭包

    bject Scala06_Function_Hell_8 {
    
        def main(args: Array[String]): Unit = {
            // Scala2.12版本前闭包功能采用的是匿名函数类型实现
            // Scala2.12版本闭包功能采用的是更改函数声明实现
    
            def outer( a : Int ) = {
                def inner( b : Int ): Int = {
                    a + b
                }
                inner _
            }
    
            //println(outer(10)(20))
            val f = outer(10)
            val ff = f(20)
    
            println(ff)
    
        }
    }
    

    5.6控制抽象

    自己一般很少使用,传参不完成 里面函数也不完整

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

    5.7函数柯里化

    声明时多个参数列表,调用时也多个参数列表

    object Scala08_Function {
    
        def main(args: Array[String]): Unit = {
    
            // TODO 函数式编程 - 柯里化(Curry)
    
            // 将无关的参数分离开
            def test( a:Int, b:Int ): Unit = {
                for ( i <- 1 to a ) { // 10min
                    println(i)
                }
                for ( j <- 1 to b ) { // 20min
                    println(j)
                }
            }
    
            def test1(a:Int)(b:Int): Unit = {
                for ( i <- 1 to a ) { // 10min
                    println(i)
                }
                for ( j <- 1 to b ) { // 20min
                    println(j)
                }
            }
    
            val a = 10 // 10min
            val b = 20 // 20min
            test(a, b) // 60min
            test1(a)(b)
        }
    }
    

    5.8递归函数

    1.scala中要求递归函数必须明确声明返回值类型

    2.函数内部调用自身

    3.一定要有跳出递归的逻辑

    4.递归函数在调用时传递的参数之间有关系 Scala中尾递归不是真正的递归,是由编译器进行了优化,形成了while循环。所以应该称之为伪递归

      // TODO 函数式编程 - 递归
            def test(): Unit = {
                test()
                println("test")
            }
            test()
           
    // 伪递归
            // 尾递归
            def test1(): Unit = {
                println("test")
                test1()
            }
            test1()
    

    5.9惰性函数

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

     def fun9(): String = {
          println("function...")
          "zhangsan"
        }
        lazy val a = fun9()
        println("----------")
        println(a)
    会推迟 println("function...")语句的输出,首次使用时,会做出输出
    
  • 相关阅读:
    企业移动化?AppCan教你正确的打开方式
    企业该如何挑选移动平台?
    除了移动开发,一个好平台还需要具备什么功能?
    canvas绘制工作流之绘制节点
    canvas与工作流的不解之缘
    一个工作流引擎诞生前的准备工作
    欢迎大家Follow me!微软MVP罗勇(Dynamics CRM方向2015-2018年)欢迎您!
    Dynamics 365定制:在实体的列表界面添加按钮
    Dynamics 365 Customer Engagement中自定义工作流活动的调试
    Dynamics CRM 2015/2016新特性之二十七:使用Web API查询元数据
  • 原文地址:https://www.cnblogs.com/xiao-bu/p/14787447.html
Copyright © 2011-2022 走看看