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...")语句的输出,首次使用时,会做出输出
posted @ 2021-05-19 21:28  triumph丶xs  阅读(60)  评论(0编辑  收藏  举报