欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理

程序员文章站 2024-02-22 21:22:10
...

1 ,面向对象编程,函数式编程 :

  1. 面向对象 : 万物皆对象。
  2. 函数式编程 : 函数是可以定义的,也可以被当做参数传递的,也可以被赋值给变量。

2 ,方法与函数 :method - function

  1. 很相似
  2. 几乎一样
  3. 方法可以转换成函数

3 ,自定义方法 :

def sum(a: Int, b: Int): Int = {
    a+b
}

4 ,方法转函数 :

var s = sum _
println(s(1,2))

5 ,自定义函数 :

def main(args: Array[String]): Unit = {
    val sum = (a:Int,b:Int) =>{
        a+b
    }
    println(sum(1,2))
}

6 ,函数更灵活

7 ,函数式编程 :

  1. 把函数当做根本的编程单位
  2. 函数也是一个对象
  3. 函数是一等公民
  4. 充分利用函数
  5. 支持函数的多种使用方式
  6. 函数可以作为参数传递给另一个函数
  7. 函数也可以作为值,传递给一个变量

8 ,函数运行过程 : 内存分析

  1. 栈 : 压栈执行,先进后出
  2. 栈 : 是一种数据结构
  3. 运行 : 不停的压栈出栈
  4. 内存图 :压栈执行,栈柄移动
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理

9 ,递归 : 入门 ( 从里到外 )

  1. 代码 :
object Aa2 {
    def main(args: Array[String]): Unit = {
        test(4)
    }
    def test(a:Int): Unit ={
        if(a>2){
            test(a-1)
        }
        println(a)
    }
}
  1. 结果 :
2
3
4
  1. 压栈执行内存图 : 递归是最适合于理解内存图的算法了
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理

10 ,递归的约束 : 不要成为死龟

递归算法,必须向着结束递归的方向逼近,不然就成为无限递归,也就是死龟。

11 ,递归练习 : 斐波那契数

  1. 数列 : 1,1,2,3,5,8,13
  2. 规律 : a3 = a2 + a1
  3. 求 : an = ?
  4. 代码 :
package com.heima.day01

object Aa2 {
    def main(args: Array[String]): Unit = {
        println(fbnq(1))
        println(fbnq(2))
        println(fbnq(3))
        println(fbnq(4))
        println(fbnq(5))
        println(fbnq(6))
        println(fbnq(7))
    }
    def fbnq(a:Int): Int ={
        if(a==1){
            return 1
        }else if(a==2){
            return 1
        }else{
            return fbnq(a-1)+fbnq(a-2)
        }
    }
}

12 ,递归练习 : 求函数值

  1. 已知 :
    f(1)=3;
    f(n) = 2*f(n-1)+1;
  2. 求 : f(n)
  3. 代码 :
package com.heima.day01

object Aa3 {
    def main(args: Array[String]): Unit = {
        println(test(1))
        println(test(2))
        println(test(3))
        println(test(4))
        println(test(5))
    }
    def test(a: Int): Int = {
        if(a==1){
            return 3;
        }else{
            2 * test(a-1)+1;
        }
    }
}

13 ,递归练习 : 猴子吃桃子问题

  1. 题设 :
    有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!以后每天猴子都吃其中的一半,然后再多吃一个。当到第十天时,想再吃时(还没吃),发现只有1个桃子了。问题:最初共多少个桃子?
  2. 代码 :
package com.heima.day01

object Aa4 {
    def main(args: Array[String]): Unit = {
        println(test(1))
    }
    def test(a:Int): Int ={
        if(a==10){
            1
        }else if(a==9){
            (1+1)*2
        }else{
            (test(a+1)+1)*2
        }
    }
}

14 ,函数使用总结 :

  1. 函数的形参列表可以是多个, 如果函数没有形参,调用时 可以不带()
  2. 形参列表和返回值列表的数据类型可以是值类型和引用类型。
  3. Scala中的函数可以根据函数体最后一行代码自行推断函数返回值类型。那么在这种情况下,return关键字可以省略
  4. 因为Scala可以自行推断,所以在省略return关键字的场合,返回值类型也可以省略
  5. 如果函数明确使用return关键字,那么函数返回就不能使用自行推断了,这时要明确写成 : 返回类型 = ,当然如果你什么都不写,即使有return 返回值为()
  6. 如果函数明确声明无返回值(声明Unit),那么函数体中即使使用return关键字也不会有返回值
  7. 如果明确函数无返回值或不确定返回值类型,那么返回值类型可以省略(或声明为Any)
  8. Scala语法中任何的语法结构都可以嵌套其他语法结构(灵活),即:函数中可以再声明/定义函数,类中可以再声明类 ,方法中可以再声明/定义方法
  9. Scala函数的形参,在声明参数时,直接赋初始值(默认值),这时调用函数时,如果没有指定实参,则会使用默认值。如果指定了实参,则实参会覆盖默认值。
    例如这样 :
def sayOk(name : String = "jack"): String = {
     return name + " ok! "
}
  1. scala 函数的形参默认是val的,因此不能在函数中进行修改。
  2. 递归函数未执行之前是无法推断出来结果类型,在使用时必须有明确的返回值类型。
  3. Scala函数支持可变参数
    1 ,args 是集合, 通过 for循环 可以访问到各个值。
    2 ,可变参数需要写在形参列表的最后。
    3 ,例子 :
//支持0到多个参数
def sum(args :Int*) : Int = { 
}
//支持1到多个参数
def sum(n1: Int, args:  Int*) : Int  = { 
}

15 ,默认参数,带名参数 :

  1. 不带名 : 默认从左到右给参数赋值
  2. 带名 : 给指定参数赋值
object Aa4 {
    def main(args: Array[String]): Unit = {
        test(b=3)
    }
    
    def test(a: Int = 1, b: Int = 2): Unit = {
        println(a+","+b)
    }
}

16 ,过程 :procedure

没有返回值的函数

17 ,惰性函数 : 节省内存开销

  1. 目的 : 不到最后一刻不开工
    1 ,如果一个计算分很多步骤。
    2 ,将必须做的事情给做了。
    3 ,不必要的事情先不做。
    4 ,用到的时候再去做。
  2. 代码 :
object Aa4 {
    def main(args: Array[String]): Unit = {
        lazy val res = test(1,2)
        println("11111111")
        println(res)
        println("22222222")
    }
    def test(a: Int = 1, b: Int = 2): Int = {
        println("开工啦")
        a+b
    }
}
  1. 结果 :
11111111
开工啦
3
22222222

18 ,异常 : 捕获异常

  1. scala 异常 : 只有一种异常,运行时异常
  2. 代码 :
def main(args: Array[String]): Unit = {
    try {
        val r = 10 / 0
    } catch {
        case ex: ArithmeticException=> println("捕获了除数为零的算数异常")
        case ex: Exception => println("捕获了异常")
    } finally {
        // 最终要执行的代码
        println("scala finally...")
    }
}

18 ,异常 : 自定义异常

object Aa4 {
    def main(args: Array[String]): Unit = {
        var t = test()
    }
    
    def test(): Nothing = {
        throw new Exception("自定义异常")
    }
}

19 ,练习 : 打印金字塔 :

  1. 代码 :
object Aa4 {
    def main(args: Array[String]): Unit = {
        for (i <- 1 to 9; if i % 2 != 0) {
            print(" " * ((9 - i) / 2))
            for (j <- 1 to i) {
                print("*")
            }
            println()
        }
    }
}
  1. 效果 :
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理

20 ,练习 : 打印九九惩乘法表

  1. 代码 :
object Aa4 {
    def main(args: Array[String]): Unit = {
        for (i <- 1 to 9; j<- 1 to 9 ) {
            print(j + " x " + i + " = " + i*j + "\t")
            if(j==i){
                println()
            }
        }
    }
}
  1. 效果 :
    9,scala 函数式编程 ( 基础 ) : 递归,函数,方法,内存图,可变参数,过程,惰性函数,异常处理
相关标签: scala