首页 > 其他 > 详细

Scala(五)--函数式编程

时间:2021-05-20 00:48:15      阅读:18      评论:0      收藏:0      [点我收藏+]

函数式编程

  1面向对象编程

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

      对象用户;

      行为:登录、连接jdbc、读取数据库

      属性:用户名、密码

    Scala语言是一个完全面向对象编程语言。万物皆对象

  2)函数式编程

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

    例如请求->用户名、密码->连接jdbc->读取数据库

    Scala语言是一个完全函数式编程语言。万物皆函数

  3)在Scala中函数式编程和面向对象编程融合在一起了。

5.1 方法基本语法

  1)基本语法

技术分享图片

  2案例实操

    需求:定义一个方法,实现将传入的名称打印出来。

package com.yuange.scala.day02

import scala.io.StdIn

object FunctionOne {
  def printName(name: String): Unit = println("name=" + name)

  def main(args: Array[String]): Unit = {
    println("请输入姓名:")
    printName(StdIn.readLine())
  }
}

技术分享图片

5.2 方法声明

  1)方法声明

    (1)方法1:无参,无返回值

    (2)方法2:无参,有返回值

    (3)方法3:有参,无返回值

    (4)方法4:有参,有返回值

  2)案例实操

package com.yuange.scala.day02

object FunctionTwo {
  def main(args: Array[String]): Unit = {
    //无参,无返回值
    def test1() : Unit = {
      println("无参无返回值")
    }

    //无参,有返回值
    def test2() : String = {
      return "无参有返回值"
    }

    //有参,无返回值
    def test3(id: Int,name: String): Unit = {
      println("id=" + id + ",name=" + name)
    }

    //有参,有返回值
    def test4(id: Int,name:String): String = {
      return "id=" + id + ",name=" + name
    }
  }
}

5.3 方法参数

  1)案例实操

    (1)可变参数

    (2)如果参数列表中存在多个参数,那么可变参数一般放置在最后

    (3)参数默认值

    (4)带名参数

package com.yuange.scala.day02

object FunctionThree {
  def main(args: Array[String]): Unit = {
    test1("李白","杜甫","白居易")
    test1()
    //可变参数
    def test1(s: String*): Unit = {
      println(s)
    }

    test2(100)
    test2(1023,"赵云","刘备","曹操")
    //若参数列表存在多个参数,则可变参数一般放置在最后
    def test2(g: Int,s: String*): Unit = {
      println("g=" + g + ",s=" + s)
    }
    /*def test2(s: String*,g Int): Unit = { //error
      println("s=" + s + ",g=" + g)
    }*/

    test3(110)
    test3(120,"救护车")
    //参数默认值
    def test3(id: Int,name: String = "卢本伟"): Unit = {
      println("id=" + id + ",name=" + name)
    }

//    test4(1003) //error,Scala函数参数传递是从左到右,将有默认值的参数放在参数列表最后
    //带名参数
    test4(name="带名参数")
    def test4(id: Int = 1002,name: String): Unit = {
      println(s"id=${id},name=${name}")
    }
  }
}

技术分享图片

5.4 方法至简原则

  方法至简原则:能省则省

  1至简原则细节

    1return可以省略,Scala会使用方法体的最后一行代码作为返回值

    (2)返回值类型如果能够推断出来,那么可以省略

    (3)如果方法体只有一行代码,可以省略花括号

    (4)如果方法无参,则可以省略小括号。若定义方法时省略小括号,则调用该方法时,也需省略小括号;若定义方法时未省略,则调用时,可省可不省。

    (5)如果方法明确声明Unit,那么即使方法体中使用return关键字也不起作用

    (6)Scala如果想要自动推断无返回值,可以省略等号

    (7)如果方法明确使用return关键字,那么方法返回就不能使用自行推断了,需要声明返回值类型

  2案例实操

package com.yuange.scala.day02

object FunctionFour {
  def main(args: Array[String]): Unit = {
    //标准写法
    def test1(name: String): String = {
      return name + "很牛逼"
    }
    println(test1("王五"))

    //return可以省略,scala会使用方法体的最后一行代码作为返回值
    def test2(name: String): String = {
      name + "牛逼Class"
    }
    println(test2("test2()孙斌"))

    //方法返回值若能推断出来,则可以省略返回值类型
    def test3(name: String) = {
      name + "十分嚣张"
    }
    println(test3("test3()张飞"))

    //若方法名使用return关键字,则方法不能使用自行推断,需声明返回值类型
    /*def test3(name: String) = { //error
      return name + "厉害"
    }*/

    //若方法体只有一行代码,则可以省略{}
    def test4(name: String) = name + "弱爆了"
    println(test4("test4()孙尚香"))

    //若方法无参,但声明了参数列表,则调用时()可加可不加
    def test5() = "test5()小括号可加可不加"
    println(test5())
    println(test5)

    //若方法无参且没有参数列表,则小括号可以省略,但调用方法时必须也省略
    def test6 = "test6()调用时必须也省略()"
//    println(test6())  //error
    println(test6)

    //若方法声明Unit,则即使方法体中使用return关键字也不会起作用
    def test7(name: String): Unit = {
      return "name=" + name
    }
    println(test7("test7()Judson"))   //打印()

    //若想自动推断无返回值,可以省略等号(等号和{}不能同时省略,将无返回值的方法称之为过程)
//    def test8(name: String) "name=" + name  //error
    def test8(name: String) {"name=" + name}
    println(test8("我是test8(),等号和{}不能同时省略"))   //打印()

    //若方法使用return关键字,则方法返回不能使用自动推断,需要声明返回值类型
    def test9(name: String): String = {  //error
        return "name=" + name
    }
    println("我是test9()")
//    def test9(name: String) = {  //error
//      return "name=" + name
//    }
  }
}

技术分享图片

5.5 函数的基本语法

  1)基本语法:

技术分享图片

    函数的返回值就是函数体中最后一个表达式的结果值

  2案例实操

    需求:定义一个函数,实现将传入的两个整数相加

package com.yuange.scala.day02

object FunctionFive {
  def main(args: Array[String]): Unit = {
    var plushFunction = (x: Int,y: Int) => {
      x + y
    }
    println(plushFunction(10,30))
  }
}

5.6 函数和方法的区别

  1)方法定义在类中可以实现重载,函数不可以重载

  2)方法是保存在方法区,函数是保存在堆中

  3)定义在方法中的方法可以称之为函数,不可以重载

  4)方法可以转成函数, 转换语法: 方法名 _

package com.yuange.scala.day02

object FunctionSix {
  //方法可以重载和重写,程序可以执行
  def main(): Unit = {

  }

  //方法
  def add(x: Int,y: Int) = x + y

  def main(args: Array[String]): Unit = {
    //可以在任何语法结构中声明任何语法
    import java.util.Date
    new Date()

    //函数没有重载和重写的概念
    var test = () => {
      println("无参无返回值")
    }
    test()
//    var test = (name: String) => {
//      println()
//    }

    //函数可以嵌套定义
    var test2 = () => {
      var test3 = () => {
        println("函数可以嵌套定义")
      }
    }

    //方法可以转成函数
    var add2 = add _
  }
}

5.7 高阶函数

  1定义:参数为函数的方法/函数称为高阶函数

  2案例实操

package com.yuange.scala.day02

object FunctionSeven {
  def main(args: Array[String]): Unit = {
    //高阶函数:以函数作为参数
    def calculator(a: Int,b: Int,operater: (Int,Int) => Int): Int = {
      operater(a,b)
    }

    //求和
    var add = (x: Int,y: Int) =>  x + y
    //求积
    var mul = (x: Int,y: Int) =>  x * y

    //调用
//    println(calculator(1,2,add))
//    println(calculator(1,2,mul))

//    println(calculator(1,2,(x,y) => x + y))  //简化
//    println(calculator(1,2,(x,y) =>  x * y))  //简化
    
    println(calculator(1,2,_ + _))  //再简化
    println(calculator(1,2,_ * _))  //再简化
  }
}

5.8 匿名函数

  1说明:没有名字的函数就是匿名函数,可以直接通过函数字面量(表达式)来设置匿名函数,函数字面量定义格式如下。

技术分享图片

  2案例实操

package com.yuange.scala.day02

object FunctionEight {
  //高阶函数:函数可以作为参数
  def calculator(a: Int,b: Int,operater: (Int,Int) => Int): Int ={
    operater(a,b)
  }

  //求和
  var add = (x: Int,y: Int) => x + y
  //求积
  var mul = (x: Int,y: Int) => x * y

  def main(args: Array[String]): Unit = {
    //函数作为参数
    println(calculator(1,4,add))

    //匿名函数作为参数
    println(calculator(2,3,(x: Int,y: Int) => x * y))

    //匿名函数简写
    println(calculator(5,8,_ * _))
  }
}

5.9 函数柯里&闭包

  1说明:函数柯里化是指将一个接收多个参数的函数转化成一个接收一个参数的函数过程,可以简单的理解为一种特殊的参数列表声明方式。

    闭包:就是一个函数和与其相关的引用环境(变量)组合的一个整体(实体)

  2案例实操

    (1)闭包

package com.yuange.scala.day02

object FunctionNine {
  //外部变量
  var a1: Int = 10
  //闭包
  def test(a2: Int): Int = {
    a1 + a2
  }
}

    (2)柯里化

package com.yuange.scala.day02

object FunctionTen {
  //柯里化
  var sum = (x: Int,y: Int,z: Int) => x + y + z
  var sum1 = (x: Int) => {
    y: Int => {
      z: Int => {
        x + y + z
      }
    }
  }
  var sum2 = (x: Int) => (y: Int) => (z: Int) => x + y + z
  def sum3(x: Int)(y: Int)(z: Int) = x + y + z

  def main(args: Array[String]): Unit = {
    println(sum(1, 2, 3))
    println(sum1(1)(2)(3))
    println(sum2(1)(2)(3))
    println(sum3(1)(2)(3))
  }
}

技术分享图片

5.10 递归

  1说明:一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用

  2案例实操

package com.yuange.scala.day02

object Recursion {
  def main(args: Array[String]): Unit = {
    /**
     * 递归算法
     * 1.方法调用自身
     * 2.方法最终能跳出循环逻辑
     * 3.方法调用自身时,传递的参数应该有规律
     * 4.scala中的递归必须声明函数返回值类型
     */
    println(test(10))
  }

  def test(a: Int): Int = {
    if (a == 1){
      1
    }else{
      a * test(a - 1)
    }
  }
}

5.11 控制抽象

  Scala中可以自己定义类似于if-elsewhile的流程控制语句,即所谓的控制抽象。

  案例:定义如下控制结构

loop(5){
  println("control")
}

  上述控制结构的功能为将println("control")循环执行5次。

  提示:scala中,以下结构称为代码块(block),可视为无参函数,作为 =>Unit类型的参数值。

{
    code
}

  实操:

package com.yuange.scala.day02

object ControlAbstraction {
  def loop(i: Int)(op: => Unit): Unit = {
    if (i > 0){
      op
      loop(i - 1)(op)
    }
  }

  def main(args: Array[String]): Unit = {
    loop(5){
      println("control")
    }
  }
}

技术分享图片

5.12 惰性求值

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

  2案例实操

package com.yuange.scala.day02

object LazyEvaluation {
  var sum = (a1: Int,a2: Int) => {
    println("sum........")
    a1 + a2
  }

  def main(args: Array[String]): Unit = {
    lazy val result = sum(2,6)  //lazy不能修饰var类型的变量
    println("result="+result)
  }
}

技术分享图片

Scala(五)--函数式编程

原文:https://www.cnblogs.com/LzMingYueShanPao/p/14783814.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!