六、函数
函数三要素:函数名、参数、函数体
声明函数语法
def functionName ([参数列表]) : [return type] = { 函数体}
示例
// 无返回值
def sayHi(str: String): Unit = {
println("Hello:" + str)
}
// 可省略返回值类型,支持自动推导
def sum(x: Int, y: Int) = x + y
def multi(x: Double, y: Double): Double = x * y
总结:
- 有返回值的函数,
: 返回值类型 = {函数代码块}
或者= {函数代码块}
- 无返回值的函数,
:Unit = {函数代码块}
或者{}
变长参数
package function
object Function02 {
// 主函数声明
def main(args: Array[String]) {
println(sum(1, 2, 3, 4, 5))
println(sum(1))
println(sum())
}
// 变长参数列表 n1 n2... nn
// 语法:变量名:类型*
def sum(nn: Int*): Int = {
var sum = 0
for (n <- nn) {
sum += n
}
sum
}
// 注意: 如果有多个参数,可变长参数需要写在所有参数之后
def sum2(default: Int,nn: Int*): Int = {
var sum = 0
for (n <- nn) {
sum += n
}
sum
}
}
参数默认值
package function
object Function03 {
def main(args: Array[String]): Unit = {
println(m1("Welcome"))
// 无给定值,使用默认值
println(m2())
// 给定值,使用给定值
println(m2("welcome", 20, 100.0))
// 部分参数使用给定值,另一部分参数使用默认值
println(m2("welcome"))
// 给特定的参数赋予给定值,其余使用默认值
println(m2(arg2 = 100))
}
// 默认值函数
def m1(arg1: String = "Hello"): String = {
arg1
}
// 默认值函数
// 注意:函数不支持重载,只有方法支持重载
def m2(arg1: String = "Hello", arg2: Int = 10, arg3: Double = 10.0): String = {
arg1 + "\t" + arg2 + "\t" + arg3
}
}
带名参数
m1(arg2 = 100, arg1 = "new value")
def m1(arg1: String = "default value1", arg2: Int = 10): Unit ={
println (arg1 + "\t" + arg2)
}
//new value <---> 100
Lazy值
懒加载,当val被声明为lazy时,它的初始化将被推迟,直到我们首次对它取值。
import scala.io.Source._
/**
* lazy值 使用时初始化 节省资源
*/
object function03 {
def main(args: Array[String]): Unit = {
val file1 = fromFile("").mkString
println(file1)
// lazy val file2 = fromFile("").mkString
// println(file2)
}
}
递归函数
递归求1到n之和
def sum(n: Int): Int = {
var total = 0
if (n >= 1) {
total = n + sum(n - 1)
}
total
}
递归求1到n的阶乘
def factorial(n: Int): Int = {
if (n > 1) {
n * factorial(n - 1)
} else {
1
}
}
匿名函数
Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体。使用匿名函数后,我们的代码变得更简洁了。
package function
/**
* 递归使用
*/
object Function05 {
def main(args: Array[String]): Unit = {
// 匿名函数: 没有函数名
val f1: Function2[Int, Int, Int] = (x: Int, y: Int) => x + y
println(f1)
val f2 = () => "Hello:"
println(f2)
val f3 = (x: Int, y: Int, z: Int) => x * y * z
println(f3)
List("a", "b").foreach(n => println(n))
/*
<function2>
<function0>
<function3>
a
b
*/
println(f1(1,2))
println(f2())
println(f2) // 打印对象,注意:没有参数的匿名函数需要加()调用
println(f3(2,2,2))
}
}
注意:
- 匿名函数返回的是一个函数对象(Function,scala提供了23个函数对象,分别对应0到22个参数)
柯里化(Currying)
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接收一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
package function
/**
* 柯里化函数(curring)
* 将多个参数的函数 转换为接收一个参数函数的过程,就称为柯里化,并返回以第二个参数为参数的函数
*/
object Function06 {
def main(args: Array[String]): Unit = {
println(sum2(1)(6))
println(sum3(1)(6))
println(sum4(1)(6)(2))
println(sum4 _)
}
// 普通函数
def sum1(x: Int, y: Int): Int = {
x + y
}
// 柯里化函数
def sum2(x: Int) = (y: Int) => x + y
// 柯里化函数 简化写法
def sum3(x: Int)(y: Int) = x + y
def sum4(x: Int)(y: Int)(z: Int) = x + y + z
}