【无标题】

一、函数的定义
1、函数定义
(1)函数 1:无参,无返回值
(2)函数 2:无参,有返回值
(3)函数 3:有参,无返回值
(4)函数 4:有参,有返回值
(5)函数 5:多参,无返回值
(6)函数 6:多参,有返回值
2、案例实操
object demo07 {
  // (1)函数1:无参,无返回值
  def test1(): Unit = {
    println("这是无参无返回值的函数")
  }
  // (2)函数2:无参,有返回值
  def test2(): Int = {
    42
  }

  // (3)函数3:有参,无返回值
  def test3(num: Int): Unit = {
    println(s"传入的参数是: $num")
  }
  // (4)函数4:有参,有返回值
  def test4(num: Int): Int = {
    num * 2
  }、
  // (5)函数5:多参,无返回值
  def test5(a: Int, b: Int): Unit = {
    println(s"传入的参数是 $a 和 $b")
  }

  // (6)函数6:多参,有返回值
  def test6(a: Int, b: Int): Int = {
    a + b
  }
  def main(args: Array[String]): Unit = {
    Test1()
    val result2 = test2()
    println(s"函数2的返回值: $result2")
   test3(5)
    val result4 = test4(3)
    println(s"函数4的返回值: $result4")
    Test5(2, 3)
    val result6 = test6(4, 5)
    println(s"函数6的返回值: $result6")
  }
}

二、函数参数
案例实操:
1、可变参数
2、如果参数列表中存在多个参数,那么可变参数一般放置在最后
3、参数默认值,一般将有默认值的参数放置在参数列表的后面
4、带名参数
object demo08 {
  // (1)可变参数
  def sumNumbers(numbers: Int*): Int = {
    var sum = 0
    for (num <- numbers) {
      sum += num
    }
    sum
  }

  // (2)可变参数放置在最后
  def printInfo(name: String, age: Int, hobbies: String*): Unit = {
    println(s"姓名: $name,年龄: $age")
    println("爱好: " + hobbies.mkString(", "))
  }

  // (3)参数默认值,有默认值的参数放在后面
  def greet(name: String, greeting: String = "Hello"): Unit = {
    println(s"$greeting, $name!")
  }
  // (4)带名参数
  def calculate(a: Int, b: Int): Int = {
    a + b
  }
  def main(args: Array[String]): Unit = {
    // 测试可变参数
    val sumResult = sumNumbers(1, 2, 3, 4, 5)
    println(s"可变参数求和结果: $sumResult")
    // 测试可变参数放置在最后
    printInfo("Alice", 25, "reading", "swimming")
    // 测试参数默认值
    greet("Bob")
    greet("Charlie", "Hi")
    // 测试带名参数
    val calcResult = calculate(b = 3, a = 2)
    println(s"带名参数计算结果: $calcResult")
  }
}

三、函数至简原则(重点)
1、至简原则细节
(1)return 可以省略,Scala 会使用函数体的最后一行代码作为返回值
(2)如果函数体只有一行代码,可以省略花括号
(3)返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)

(4)如果有 return,则不能省略返回值类型,必须指定
(5)如果函数明确声明unit,那么即使函数体中使用 return 关键字也不起作用
(6)Scala 如果期望是无返回值类型,可以省略等号
(7)如果函数无参,但是声明了参数列表,那么调用时,小括号,可加可不加
(8)如果函数没有参数列表,那么小括号可以省略,调用时小括号必须省略
(9)如果不关心名称,只关心逻辑处理,那么函数名(def)可以省略
object demo09{
  // 体现原则(1)(2)(3)
  // return省略,函数体只有一行省略花括号,返回值类型可推断所以省略
  def add(a: Int, b: Int) = a + b 
  // 体现原则(4)
  // 有return,明确指定返回值类型
  def subtract(a: Int, b: Int): Int = {
    return a - b
  }
  // 体现原则(5)
  // 函数声明为Unit,return不起作用
  def printResult(result: Int): Unit = {
    return println(s"计算结果是: $result")
  }
  // 体现原则(6)
  // 无返回值类型,省略等号
  def logMessage(message: String) =println(s"日志: $message") 
  // 体现原则(7)
  // 无参函数声明了参数列表,调用时括号可加可不加
  def getSystemInfo(): String = "Scala程序信息"
  // 体现原则(8)
  // 没有参数列表,调用时括号必须省略
  val programVersion = "v1.0"
  // 体现原则(9)
  // 匿名函数,不关心名称,只关注逻辑
  val multiply = (a: Int, b: Int) => a * b

  def main(args: Array[String]): Unit = {
    val sumResult = add(3, 5)
    val diffResult = subtract(5, 3)
    printResult(sumResult)
    logMessage("执行加法和减法运算")
    val info1 = getSystemInfo()
    val info2 = getSystemInfo // 调用时括号省略
    println(s"系统信息1: $info1,系统信息2: $info2")
    println(s"程序版本: $programVersion")
    val productResult = multiply(4, 6)
    println(s"乘法结果: $productResult")
  }
}

四、高阶函数
1、函数可以作为值进行传递
object demo10 {
    def calc(): Int = {
      println("执行计算操作")
      4 + 5
    }
  def main(args: Array[String]): Unit = {
    // (1)调用calc函数,把返回值给变量res
    // val res = calc()  // 原注释方式
    val res = calc
    println(res)
    // (2)将calc函数整体传递给变量calcFunc
    val calcFunc = calc
    calc()
    calcFunc()
    // (3)如果明确变量类型,那么不使用下划线也可以将函数作为整体传递给变量
    var anotherCalc: () => Int = calc
  }
}

2、函数可以作为参数进行传递
object demo11 {
  def main(args: Array[String]): Unit = {
    // (1)定义一个函数,函数参数还是一个函数签名;f表示函数名称;(Int, Int)表示输入两个Int参数;Int表示函数返回值
    def f1(f: (Int, Int) => Int): Int = {
      f(3, 5)
    }
    // (2)定义一个函数,参数和返回值类型和f1的输入参数一致
    def multiply(a: Int, b: Int): Int = {
      a * b
   }
    // (3)将multiply函数作为参数传递给f1函数,如果能够推断出来不是调用,可以省略
    println(f1(multiply))
    println(f1(multiply _))
    // 传递匿名函数
    println(f1((x: Int, y: Int) => x - y))
  }
}

3、函数可以作为函数返回值返回
object demo12 {
  def main(args: Array[String]): Unit = {
    // 定义函数f1,它返回一个函数
    def f1(): () => Int = {
      def f2(): Int = {
        println("调用内部函数f2")
        42
      }
      f2
    }
    // 将f1的返回值赋给变量f
    val f = f1()
    // 调用f,实际是调用f1返回的f2函数
    val result1 = f()
    println(s"结果1: $result1")
    // 简化写法
    val result2 = f1()()
    println(s"结果2: $result2")
  }
}

五、匿名函数
1、说明
没有名字的函数就是匿名函数。(x:Int)=>{函数体}x:表示输入参数类型;Int:表示输入参数类型;函数体:表示具体代码逻辑2)
2、案例实操:传递的函数有一个参数传递匿名函数至简原则:
(1)参数的类型可以省略,会根据形参进行自动的推导
(2)类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参数超过 1 的永远不能省略圆括号。
(3)匿名函数如果只有一行,则大括号也可以省略
(4)如果参数只出现一次,则参数省略且后面参数可以用_代替
object demo13 {
  def main(args: Array[String]): Unit = {
    // 定义一个接收函数作为参数的高阶函数,该参数函数接收一个Int类型参数,返回Int类型结果
    def operateOnNumber(num: Int, operation: Int => Int): Int = {
      operation(num)
    }
    // 完整写法的匿名函数
    val result1 = operateOnNumber(5, (x: Int) => {
      x * x
    })
    println(s"完整写法结果: $result1")
    // 根据原则(1)省略参数类型
    val result2 = operateOnNumber(5, (x) => {
      x * x
    })
    println(s"省略参数类型结果: $result2")

    // 根据原则(2),只有一个参数时省略圆括号
    val result3 = operateOnNumber(5, x => {
      x * x
    })
    println(s"省略圆括号结果: $result3")
    // 根据原则(3),函数体只有一行时省略大括号
    val result4 = operateOnNumber(5, x => x * x)
    println(s"省略大括号结果: $result4")
    // 根据原则(4),参数只出现一次时省略参数并用_代替
    val result5 = operateOnNumber(5, (x)=> {x * x)})
    println(s"参数省略结果: $result5")
  }
}

六、函数柯里化&闭包
1、说明
(1)闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的环境,称为闭包
(2)函数柯里化:把一个参数列表的多个参数,变成多个参数列表。
2、案例实操
object demo14 {
  def main(args: Array[String]): Unit = {
    // 定义函数f1,在其内部定义局部变量和函数
    def f1() = {
      var num = 5
      def f2(x: Int) = {
        num + x
      }
      f2_
    }
    // 调用f1获取函数f2
    val func = f1()
    // 调用f2函数并传入参数3
    println(func(3))
    // 另一种调用方式
    println(f1()(3))
  }
}

七、递归
1、说明
一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用
2、案例实操
object demo15{
  def main(args: Array[String]): Unit = {
    // 计算斐波那契数列第n项,使用递归
    def fibonacci(n: Int): Int = {
      // 跳出递归的逻辑:第0项和第1项的值
      if (n == 0) 0
      else if (n == 1) 1
      else // 递归调用自身,参数有规律递减
        fibonacci(n - 1) + fibonacci(n - 2)
    }
    println(fibonacci(10))
  }
}

八、控制抽象
案例实操:
object demo16 {
  def main(args: Array[String]): Unit = {
    // 名调用示例:传递代码块
    bar({
      println("执行名调用代码块")
      10
    })
    // 小括号省略形式的名调用
    bar {
      println("另一种名调用代码块")
      20
    }

    // 自定义条件循环
    var count = 0
    myWhile(count < 3) {
      println(s"当前count: $count")
      count += 1
    }
  }

  // 定义接受名调用参数的函数
  def bar(a: => Int): Unit = {
    println(s"传入的值: $a")
    println(s"再次使用传入的值: $a")
  }

  // 自定义while循环函数
  def myWhile(condition: => Boolean)(block: => Unit): Unit = {
    if (condition) {
      block
      myWhile(condition)(block)
    }
  }
}

九、惰情加载
1、说明
当函数返回值被声明为 lazy 时,函数的执行将被推迟,直到我们首次对此取值,该函数才会执行。这种函数我们称之为惰性函数
2、案例实操:
object demo17 {
  def main(args: Array[String]): Unit = {
    // 使用lazy关键字修饰val变量,延迟函数执行
    lazy val result = multiply(3, 4)
    println("程序在继续执行其他操作...")
    println(s"result的值为: $result")
  }
  def multiply(n1: Int, n2: Int): Int = {
    println("multiply函数被执行")
    n1 * n2
  }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值