函数定义与使用
方法定义由一个 def 关键字开始,紧接着是可选的参数列表,一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。
def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
以上代码中 return type 可以是任意合法的 Scala 数据类型。参数列表中的参数可以使用逗号分隔。
函数定义与调用实列
object Function {
def main(args: Array[String]): Unit = {
//当形参数量为0时括号可以不写
sayHello
sayHello("xiaoming")
println(add(1, 2))
//当函数体只有一行时{}可以不写
def simpleAdd(x: Int, y: Int) = x + y
println(simpleAdd(1, 2))
}
//无返回值函数
def sayHello(): Unit = {
println("say hello")
}
def sayHello(name: String): Unit = {
println(s"$name hello")
}
//有返回值函数 以Int为列
def add(x: Int, y: Int): Int = {
x + y //最后一行为返回值 无需return
}
}
默认参数
scala在函数定义时允许指定参数的默认值,当参数调用时若不传递该参数则为默认值,若传则以你传的参数为准。
注意:
- 调用只有一个默认参数的函数时,()不可以省略
object DefaultParamFunction {
def main(args: Array[String]): Unit = {
//注意默认参数时,()不可以省略
sayHello() //xiaoming say hello
sayHello("agou") //agou say hello
}
def sayHello(name: String = "xiaoming"): Unit = {
println(s"$name say hello")
}
}
传名调用
写在前面: 本模块部分内容借鉴了狗叔的博客(Scala从零开始:函数参数的传名调用(call-by-name)和传值调用(call-by-value))
简单示例
object CallByName {
def main(args: Array[String]): Unit = {
param2(param1())
}
def param1() = {
println("param1函数======")
100
}
def param2(t: => Int) = {
println(s"param2打印t======$t")
}
}
传名调用与传值调用的区别
传值调用方式:就是在调用之前已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。
object Add {
//传名调用
def addByName(a: Int, b: => Int) = a + b
//传值调用
def addByValue(a: Int, b: Int) = a + b
}
当纯从语法上可以看出,使用传名调用时,在参数名称和参数类型中间有一个=》符号。
以a为2,b为2 + 2为例,他们在Scala解释器进行参数规约(reduction)时的顺序分别是这样的:
addByName(2, 2 + 2)
->2 + (2 + 2)
->2 + 4
->6
addByValue(2, 2 + 2)
->addByValue(2, 4)
->2 + 4
->6
你可能会说结果不都是6吗??没有区别啊,那么回头看看我们之前所说的传名调用是在函数内部进行参数表达式的值计算的, 再仔细看2+(2+2)与2+4其实是有很大区别的。这种区别明显体现在循环时的重复调用,我们看下面这个列子,你就会发现传名调用是每次都会算一下,而传值调用是在调用前就算好了以后都不会再算了。
object CallByName {
//最开始拥有的软妹币
var money = 10
//每天喝掉一个软妹币
def drink: Unit = {
money -= 1
}
//数钱时要算上被喝掉的软妹币
def count: Int = {
drink
money
}
//传名调用
def printByName(x: => Int): Unit = {
for(i <- 0 until 5)
println("每天算一算,酒鬼还剩" + x + "块钱!")
}
//传值调用
def printByValue(x: Int): Unit = {
for(i <- 0 until 5)
println("只算第一天,酒鬼还剩" + x + "块钱!")
}
def main(args: Array[String]) = {
printByName(count)
printByValue(count)
}
}
结果:
每天算一算,酒鬼还剩9块钱!
每天算一算,酒鬼还剩8块钱!
每天算一算,酒鬼还剩7块钱!
每天算一算,酒鬼还剩6块钱!
每天算一算,酒鬼还剩5块钱!
只算第一天,酒鬼还剩4块钱!
只算第一天,酒鬼还剩4块钱!
只算第一天,酒鬼还剩4块钱!
只算第一天,酒鬼还剩4块钱!
只算第一天,酒鬼还剩4块钱!
可变参数
/**
* 以求和计算为列,计算两个数我们需要定义一个函数入参数为a、b,计算三个数的和我们需要定义a、b、c,
* 那么这样我们就可以使用可变参数,也就是你想传多少参数就传多少个
*/
object Varargs {
def main(args: Array[String]): Unit = {
println(sum(1, 2, 3, 4))
}
def sum(numbers: Int*) = {
var sum = 0;
for (number <- numbers) {
sum += number;
}
sum
}
}