Scala里有方法和函数,第一感觉两者应该没啥区别吧,其实不然,Scala方法是类的一部分,而函数是一个对象,可以赋值给一个变量,换言之,在类中的函数就是方法。
Scala里可以用 val 定义函数,用 def 定义方法
class Test {
def method1(a: Int, b:Int) = {
return a+b
}
val f = (x:Int) => x+3
}
方法的定义
Scala方法定义格式如下:
def functionName([参数列表]):返回类型 = {
function body
return expr
}
我们看一个例子
object add {
def main(args: Array[String]) {
println("method addInt: ", addInt(2,4))
printMe()
}
def addInt(a:Int, b:Int):Int ={
var sum: Int = 0
sum = a + b
sum
}
def printMe():Unit = {
println("printMe")
}
}
执行结果如下:
(method addInt: ,6)
printMe
函数传名调用
scala的解释器在解析函数调用参数时有两种方式
- 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部
- 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部
我们看一个例子:
object Test {
def main(args: Array[String]) {
timeDelayed(getTime());
}
def getTime() = {
println("获取时间,单位为纳秒")
System.nanoTime
}
def timeDelayed( t: => Long ) = {
println("在 delayed 方法内")
println("参数: " + t)
t
}
}
运行结果如下:
在timeDelayed方法内
获取时间,单位是纳秒
(参数: 21847264195735)
获取时间,单位是纳秒
这里很神奇,为啥会输出两条 “获取时间,单位是纳秒”。其实是因为我们在timeDelayed方法里设置了传名调用,就是在参数和变量类型直接加了一个 “=>”,因此在执行 timeDelayed(getTime()) 时,首先执行timeDelayed()方法里第一个输出,表示进入了该方法,接着打印接收到的参数值,最后再返回 t
指定函数参数名
一般情况下,函数调用参数会按照定义时的顺序一个一个调用,Scala里也可以指定函数参数名,不用按照参数顺序传递。
object Test {
def main(args: Array[String]) {
printInt(b=5, a=7);
}
def printInt( a:Int, b:Int ) = {
println("Value of a : " + a );
println("Value of b : " + b );
}
}
执行结果:
Value of a : 7
Value of b : a
可变参数
Scala 允许我们不用指定参数个数,传入可变长度的参数列表。通过在参数的类型后面加一个星号
object Test {
def main(args: Array[String]) {
printStrings("python", "Scala", "ruby");
}
def printStrings( args:String* ) = {
var i : Int = 0
for( arg <- args ){
println("Arg value[" + i + "] = " + arg )
i = i + 1
}
}
}
执行结果:
Arg value[0] = python
Arg value[1] = Scala
Arg value[2] = ruby
递归函数
递归函数在编程里起到非常重要的作用,我们以计算阶乘为例。
object Test {
def main(args: Array[String]) {
for (i <- 1 to 10)
println(i + " 的阶乘为: " + factorial(i) )
}
def factorial(n: BigInt): BigInt = {
if (n <= 1)
1
else
n * factorial(n - 1)
}
}
运行结果:
1 的阶乘是: 1
2 的阶乘是: 2
3 的阶乘是: 6
4 的阶乘是: 24
5 的阶乘是: 120
6 的阶乘是: 720
7 的阶乘是: 5040
8 的阶乘是: 40320
9 的阶乘是: 362880
10 的阶乘是: 3628800