Scala——函数的使用

99 阅读3分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

函数

要定义函数,需要给出函数的名称、参数和函数体:

def abs(x:Double) = if (x>0) x else -x

必须给出所有参数的类型,不过,只要函数不是递归的,就不需要指定返回类型。Scala编译器可以通过 = 右侧的表达式推断出返回类型

如果函数体需要多个表达式完成,可以使用代码块,块中最后一个表达式的值就是函数的返回值。

默认参数和带名参数

scala中可以给函数提供默认参数

def main(args: Array[String]): Unit = {
    def func(x:Int=1) ={
         if (x>1) x else 0
    }
    println(func(20))
    println(func())     **//在没有传入参数的时候 函数自动使用其定义的默认值**
  }
———————————————————————————————————————————————
输出:
20
0

函数的递归

对于递归函数必须指定返回类型

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

    def func(x: Int = 1, n: Int): Int = {
      if (x >= n)
        x
      else
        x + func(x + 1, n)
    }

    println(func(n = 100))
  }
_________________________________
输出:
5050

匿名函数

写法如下:

val/var变量名称(参数类型,参数类型)返回值(形参1,形参2)结构体val/var 变量名称 ⇒(参数类型,参数类型)⇒返回值⇒(形参1,形参2)⇒{结构体}

或者使用

val/var变量名称=(形参:参数类型,形参:参数类型)逻辑结构val/var 变量名称 = (形参:参数类型,形参:参数类型)⇒逻辑结构

def main(args: Array[String]): Unit = {
    val func: (Int, Int) => Int = (a, b) => {
      a + b
    }
    val function= (a:Int, b:Int) => {
      a + b
    }
    println(func(3, 4))
    println(function(3, 4))
  }
___________________________________________
输出:
7
7

嵌套函数

可以在 Scala 函数内定义函数,定义在函数内的函数称之为局部函数

**理论上是可以↓**
def main(args: Array[String]): Unit = {
    def function0(): Unit = {
      def function1(): Unit = {
        def function2(): Unit = {
          def function3(): Unit = {
            def function4(): Unit = {
					      		⊙
            }
          }
        }
      }
    }
  }
}

可变参数

scala中还支持接收可变长度参数列表:在形参类型的后方带入*****即代表是可变长参数

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

  def func(arr:Int*****): Unit ={
        arr.foreach(print(_))
    println()
  }

  func(1,2,3,4)
  func(4,5,6,7,9)
}
————————————————————————————————————————
输出:
1234
45679

函数得到的是一个类型为 Seq 的参数。

如果你已经有一个值的序列,则不能直接将它传进上述函数。

如果 sum 函数被调用时传入的是单个参数,那么该参数必须是单个整数,而不是一个整数区间。解决这个问题的办法是告诉编译器你希望这个参数被当作参数序列来处理,追加 :_* 。

def main(args: Array[String]): Unit = {
    def sum(args: Int*): Int = {
      var result = 0
      for (arg <- args)
        result += arg
      result
    }

    //   val s = sum(1 to 5)      //错误
    val s = sum(1 to 5: **_***) //正确
    println(s)

  }

偏应用函数

偏应用函数是一种表达式,你不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数,下划线(_)替换缺失的参数。

def main(args: Array[String]): Unit = {
    //定义函数
    def logger(date: Date, level: String, message: String): Unit = {
      println(s"$date\t$level\t$message")
    }
    //正常使用函数
    logger(new Date(), "info", "ok")
    //定义偏应用函数表达式
    val info = logger(_: Date, "info", _: String)
    val error = logger(_: Date, "error", _: String)
    //使用偏应用函数
    info(new Date, "ok")
    error(new Date, "error")
  }

——————————————————————————————————————————————————————————————
输出:
Thu Dec 09 15:17:29 CST 2021	info	ok
Thu Dec 09 15:17:29 CST 2021	info	ok
Thu Dec 09 15:17:29 CST 2021	error	error

高阶函数

  • 高阶函数的参数有可能用的是另一个函数。
  • 高阶函数的返回值有可能是一个函数。
def main(args: Array[String]): Unit = {
    //函数作为接受参数:
    def computer(a: Int, b: Int, f: (Int, Int) => Int): Unit = {
       val res: Int = f(a, b)
        println(res)
    }
    computer(3, 8, (x: Int, y: Int) => {x + y })
    computer(3, 8, (x: Int, y: Int) => { x * y })
    computer(3, 8, _ * _)
    //函数作为返回值:
    def factory(i: String): (Int, Int) => Int = {
      def plus(x: Int, y: Int): Int = {
        x + y
      }
      if (i.equals("+")) {
        plus
      } else {
        (x: Int, y: Int) => { x * y }
      }
    }
    computer(3, 8, factory("-"))
  }

柯里化

柯里化就是未使用全部的参数列表调用多参数列表的方法时,会得到一个函数,该函数接收前面未使用的参数列表作为其参数。

  • 方法可以定义多个参数列表,一个()包含的内容即为一个参数列表。
def main(args: Array[String]): Unit = {
    def add(a: Int*)(b: String*) = {
      a.foreach(print)
      println
      b.foreach(print)
      println
    }
    add(1, 2, 3, 34)("this\t", "is\t", "scala\t")
  }

——————————————————————————————————————————
輸出:
12334
this	is	scala

*.方法

def main(args: Array[String]): Unit = {
    def add(a: Int*) = {
      var result = 0;
      a.foreach(result += _)
      result
    }
    val func = add _  //把add函数赋值给func
    val sums = for (i<-1 to 3 ) yield  i  //返回集合
    println(func(sums)) //使用func
  }
**_______________________________________
输出:
6**