Scala学习之(五)函数式编程


目录

一、函数基础

1、函数的基本语法

2、函数的方法的区别

3、函数定义

4、函数参数

5、函数至简原则

二、函数高级

1.高阶函数

2.匿名函数

3.函数柯里化&闭包

4.递归

5.控制抽象

6.惰性求值






一、函数基础

1)面向对象编程

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

对象:用户;

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

属性:用户名、密码

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

2)函数式编程

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

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

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

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

1、函数的基本语法

1)基本语法

      

2)案例实操

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

object TestFunction {

    def main(args: Array[String]): Unit = {

        // 1 方法声明

        def f(arg: String): Unit = {

            println(arg)

        }

        // 2 方法调用

        // 方法名(参数)

        f("hello world")

    }
}

2、函数的方法的区别

1)方法定义在类中可以实现重载,函数不可以重载
2)方法是保存在方法区,函数是保存在堆中
3)定义在方法中的方法可以称之为函数,不可以重载
4)方法可以转成函数, 转换语法: 方法名

object TestFunction {

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

}
//定义一个方法
def add(x:Int,y:Int) = x+y

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

        //函数没有重载和重写的概念,程序报错
        val test =()=> {
            println("无参,无返回值")
        }
        test()

        val test = (name:String)=>{
            println()
        }

        //(3)scala中函数可以嵌套定义
        val test2 = ()=>{

            val test3 = (name:String)=>{
                println("函数可以嵌套定义")
            }
        }
		//(4) 方法可以转成函数
        val add2 = add _
    }
}

3、函数定义

1)方法声明

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

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

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

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

(5)方法5:多参,无返回值

2)案例实操

package com.test.chapter06

object TestFunctionDeclare {

    def main(args: Array[String]): Unit = {

        // 方法1:无参,无返回值
        def test(): Unit ={
            println("无参,无返回值")
        }
        test()

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

        // 方法3:有参,无返回值
        def test3(s:String):Unit={
            println(s)
        }
        test3("jinlian")

        // 方法4:有参,有返回值
        def test4(s:String):String={
            return s+"有参,有返回值"
        }
        println(test4("hello "))


        // 方法5:多参,无返回值
        def test5(name:String, age:Int):Unit={
            println(s"$name, $age")
        }
        test5("dalang",40)
    }
}

4、函数参数

 1)案例实操
(1)可变参数
(2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
(3)参数默认值
(4)带名参数

object TestFunction {

    def main(args: Array[String]): Unit = {

        // (1)可变参数
        def test( s : String* ): Unit = {
            println(s)
        }

        // 有输入参数:输出 Array
        test("Hello", "Scala")

        // 无输入参数:输出List()
        test()

        // (2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
        def test2( name : String, s: String* ): Unit = {
            println(name + "," + s)
        }
        /*
        可变参数一般放置在最后
        def test2( s: String*,name : String ): Unit = {
            println(name + "," + s)
        }
        */
        test2("jinlian", "dalang")

        // (3)参数默认值
        def test3( name : String, age : Int = 30 ): Unit = {
            println(s"$name, $age")
        }

        // 如果参数传递了值,那么会覆盖默认值
        test3("jinlian", 20)

        // 如果参数有默认值,在调用的时候,可以省略这个参数
        test3("dalang")


        def test4( sex : String = "男", name : String ): Unit = {
            println(s"$name, $sex")
        }

        // scala函数中参数传递是,从左到右
        // 一般情况下,将有默认值的参数放置在参数列表的后面
//        test4("wusong")

        //(4)带名参数
        test4(name="ximenqing")
    }
}

5、函数至简原则

方法至简原则:能省则省

1)至简原则细节

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

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

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

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

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

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

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

(8)如果不关系名称,只关心逻辑处理时,那么函数名(def)可以省略

2)案例实操

object TestFunction {

    def main(args: Array[String]): Unit = {

        // 0)方法标准写法
        def f1( s : String ): String = {
            return s + " jinlian"
        }
        println(f1("Hello"))

        // 至简原则:能省则省

        //(1) return可以省略,scala会使用方法体的最后一行代码作为返回值
        def f2( s : String ): String = {
            s + " jinlian"
        }
        println(f2("Hello"))

        // 如果方法名使用return关键字,那么方法就不能使用自行推断了,需要声明返回值类型
        /*
        def f22(s:String)={
            return "jinlian"
        }
        */
        
        //(2)返回值类型如果能够推断出来,那么可以省略
        def f3( s : String ) = {
            s + " jinlian"
        }

        println(f3("Hello"))

        //(3)如果方法体只有一行代码,可以省略花括号
        //def f4(s:String) = s + " jinlian"
        //def f4(s:String) = "jinlian"
        def f4() = " dalang"

        // 如果方法无参,但是声明参数列表,那么调用时,小括号,可加可不加。
        println(f4())
        println(f4)

        //(4)如果方法没有参数列表,那么小括号可以省略,调用时小括号必须省略
        def f5 = "dalang"
        // val f5 = "dalang"

        println(f5)

        //(5)如果方法明确声明unit,那么即使方法体中使用return关键字也不起作用
        def f6(): Unit = {
            //return "abc"
            "dalang"
        }
        println(f6())

        //(6)scala如果想要自动推断无返回值,可以省略等号
        // 将无返回值的方法称之为过程
        def f7() {
            "dalang"
        }
        println(f7())

        //(7)如果方法明确使用return关键字,那么方法返回就不能使用自行推断了,需要声明返回值类型
        def f8() :String = {
            return "ximenqing"
        }
        println(f8())

    }
}




二、函数高级




1.高阶函数

1)说明
    定义:参数为函数的方法/函数称为高阶函数
2)案例实操

object TestFunction {

    def main(args: Array[String]): Unit = {

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

        //函数————求和
        def plus(x: Int, y: Int): Int = {
            x + y
        }

        //方法————求积
        def multiply(x: Int, y: Int): Int = {
            x * y
        }

        //函数作为参数
        println(calculator(2, 3, plus))
        println(calculator(2, 3, multiply))
    }
}




2.匿名函数

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

没有函数名:

匿名函数的作用:匿名函数一般用于给高阶函数传参。

(name:String) => { println(name) }

  (name:String) => print(name)

省略原则:

  1. 参数的类型可以省略,会根据形参进行自动的推导

  2. 类型省略之后,发现只有一个参数,则圆括号可以省略,

    其他情况:没有参数和参数超过1的永远不能省略圆括号
  3. 匿名函数如果只有一行,则括号可以省略

  4. 如果参数只出现一次,则参数省略且后面参数可以用_代替。

  5. 如果可以推断出,当前出入的println是一个函数体,而不是调用语句,则可以直接省略下划线

 

2)案例实操

object TestFunction {
    //高阶函数————函数作为参数
    def calculator(a: Int, b: Int, operator: (Int, Int) => Int): Int = {
        operator(a, b)
    }

    //函数————求和
    def plus(x: Int, y: Int): Int = {
        x + y
    }
    def main(args: Array[String]): Unit = {

        //函数作为参数
        println(calculator(2, 3, plus))

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

        //匿名函数简写形式
        println(calculator(2, 3, _ + _))
    }
}




3.函数柯里化&闭包

 1)说明
函数柯里化:将一个接收多个参数的函数转化成一个接受一个参数的函数过程,可以简单的理解为一种特殊的参数列表声明方式。
闭包:就是一个函数和与其相关的引用环境(变量)组合的一个整体(实体)

        另一种说法:
2)案例实操
    (1)闭包

//外部变量
var z: Int = 10
//闭包
def f(y: Int): Int = {
      z + y
}

    (2)柯里化

object TestFunction {
  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

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

4.递归

1)说明
    一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用
2)案例实操

object TestFunction {

    def main(args: Array[String]): Unit = {

        // 阶乘
        // 递归算法
        // 1) 方法调用自身
        // 2) 方法必须要有跳出的逻辑
        // 3) 方法调用自身时,传递的参数应该有规律
        // 4) scala中的递归必须声明函数返回值类型

        println(test(5))
    }

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

5.控制抽象

    Scala中可以自己定义类似于if-else,while的流程控制语句,即所谓的控制抽象。
案例:定义如下控制结构
    loop(5) {
      println("control")
}
上述控制结构的功能为将println("control")循环执行5次。
提示:scala中,以下结构称为代码块(block),可视为无参函数,作为 =>Unit类型的参数值。
{
    code
}
实操

object TestBlock {

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

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

  }
}

6.惰性求值

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

def main(args: Array[String]): Unit = {

    lazy val res = sum(10, 30)
    println("----------------")
    println("res=" + res)
}

val sum =(n1: Int, n2: Int)=> {
    println("sum被执行。。。")
    return n1 + n2
}


输出结果:
----------------
sum被执行。。。
res=40
注意:lazy不能修饰var类型的变量

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Scala函数式编程》是一本非常实用的Scala编程书籍,旨在教读者如何使用Scala编程语言实现函数式编程。该书通过具体的实例和案例来阐述Scala函数式编程的核心概念和技术,包括函数式编程基础、函数的高阶抽象、类型系统、模式匹配、并发编程、I/O 和异常处理等方面内容。这些知识点包含了Scala编程语言的重要概念,可以帮助读者深入掌握Scala函数式编程的技术,并在实际应用中运用它们。此外,该书也涵盖了Scala代码风格和整洁性等方面,对编成良好的代码有很大的帮助。总之,这本书对于学习Scala函数式编程的人来说是非常有实践价值的一本书籍。 ### 回答2: Scala函数式编程的PDF是一本非常有价值的学习资料。对于想要深入学习Scala函数式编程开发者,这本书提供了全面详尽的指导和实践经验,帮助开发者理解函数式编程的核心概念和思想,并将其应用于Scala程序开发中。 该书主要包括以下内容: 1.函数式编程的基本概念和原则,如不可变性、高阶函数、currying、尾递归等等。 2.函数式数据结构和算法的实现,包括列表、栈、队列、树、图等等。 3.如何使用Scala语言支持函数式编程的特性,如case class、模式匹配、参数化类型、协变和逆变等等。 4.如何使用Scala函数式编程框架,如Akka、Spark等来构建高效的分布式应用。 这本书主要适合已经有一定Scala编程基础或者其他函数式编程语言经验的开发者阅读,由于书中的内容较为深入和专业,对于初学者不太友好。但对于有一定基础的Scala开发者来说,该书是一本非常有价值的参考资料,可以帮助他们更深入地理解Scala函数式编程,提高代码质量和开发效率。 ### 回答3: Scala是一种支持函数式编程范式的编程语言,从而满足了编程语言发展中对于高度抽象和复杂数据处理的需求。Scala函数式编程pdf是一个学习Scala函数式编程理论和实践的重要资源。 Scala函数式编程pdf包含Scala函数式编程核心概念和技术,例如高阶函数、不可变性、模式匹配和递归等。它还涵盖了Scala函数式编程中的一些常见问题和解决方案,以及Scala函数式编程如何与面向对象编程 (OOP)相融合等。 Scala函数式编程pdf还提供了丰富的实际案例,包括使用Scala函数式编程技术实现算法、数据处理、Web应用程序、分布式编程等等。 总之,Scala函数式编程pdf是Scala程序员学习和实践函数式编程的重要资源,它提供了理论、实践和案例相结合的综合性学习体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值