Scala学习笔记——方法与函数
一、scala方法
Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
方法声明:
Scala 方法声明格式如下:
- def functionName ([参数列表]) : [return type] = {}
如果你不写等于号和方法主体,那么方法会被隐式声明为抽象(abstract),包含它的类型于是也是一个抽象类型。
def addNum(a : Int, b : Int) : Int = {
return a + b
}
//如果没有返回值,则返回类型用Unit,相当于void
def helloWord () : Unit = {
println("hello Scala")
}
def main(args: Array[String]): Unit = {
var a = 10
var b = 4
println(addNum(a, b))
helloWord()
}
输出:
二、scala函数
scala函数,scala的函数与方法在语义上的区别很小(其实函数就是匿名方法)
最大的区别在于函数可以作为变量传入方法中
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
格式
- val 方法名 = (参数) => 输出
//定义一个函数
val f1: (Int, Int) => Int = (x: Int, y: Int) => x + y
//将函数当做参数传入方法中
def addNum(f: (Int, Int) => Int): Int = {
f(2, 8)
}
def addNum2(a: Int, b: Int) : Int = {
return a + b
}
def main(args: Array[String]): Unit = {
val f2 = (x: Int, y: Int) => x * y
println(addNum(f2))
//方法转函数
//可以在函数后面加空格下划线( _),将方法转成函数
println(addNum(addNum2 _))
//如果传递的是方法,scala会将方法自动转换为函数传入到方法中
println(addNum(addNum2))
val f3 = addNum2 _
println(addNum(f3))
}
输出:
三、传值调用与传名调用
Scala的解释器在解析函数参数(function arguments)时有两种方式:
- 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
- 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部
在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。
这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。
def getTime() : Long = {
println("获取当前时间的时间戳:")
return System.nanoTime()
}
def printTime(t : => Long) : Long = {
println("printTime方法")
println(s"当前时间的时间戳:$t")
t
}
def printTime2(t : Long) : Long = {
println("printTime方法")
println(s"当前时间的时间戳:$t")
t
}
def main(args: Array[String]): Unit = {
//传名调用:对参数使用 参数名: => 参数类型 这样的格式,如
printTime(getTime())
//可以发现如果使用传名调用,那么每次使用参数都会计算一次表达式的值
println("-----------------------------------------")
//传值调用
printTime2(getTime())
//可以发现,虽然使用了两次t,但是表达式只计算了一次,而且是在运行getTime函数之前计算的
}
输出:
四、可变长参数与默认参数
1、可变长参数
Scala允许你指明函数的最后一个参数可以是重复的
即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。
Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)
2、默认参数
Scala 可以为函数参数指定默认参数值,使用了默认参数,你在调用函数的过程中可以不需要传递参数,
这时函数就会调用它的默认参数值,如果传递了参数,则传递值会取代默认值
3、例子
def printStr(strs: String*): Unit = {
for (str <- strs) {
print(str + " ")
}
}
def addNum(a: Int = 3, b: Int = 4): Int = {
a + b
}
def log(date: Date, message: String) = {
println(date + "----" + message)
}
def main(args: Array[String]): Unit = {
//TODO :Scala允许你指明函数的最后一个参数可以是重复的,
//即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。
//Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)
printStr("你", "好", "Scala")
println()
//Scala 可以为函数参数指定默认参数值,使用了默认参数,你在调用函数的过程中可以不需要传递参数,
// 这时函数就会调用它的默认参数值,如果传递了参数,则传递值会取代默认值
println(addNum())
println(addNum(10, 20))
}
输出:
五、闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
其实也可以理解为函数外的参数变为一个默认参数传入函数中
var factor = 2
val f1: Int => Int = (i: Int) => i * factor
def main(args: Array[String]): Unit = {
println(f1(1))
println(f1(2))
}
输出: