scala中的函数

函数定义

在scala中定义函数,需要给出 函数名、参数、函数体。例如:
def abs (x: Double) = if (x > 0) x else -x
如果有参数,必须要给出参数类型。如果函数不是递归的,返回值类型就可以不写。scala编译器自带类型推导功能。
如果函数体由多个表达式组成,可以用代码块的方式来组织,比如:
def fac (n: Int) = {
var r =1
for(i <- 1 to n) r = r * i
r
}
在scala函数中,不推荐使用return来退出函数,虽然可以使用,但是要尽量避免。

对于递归函数,就必须指定返回值类型,因为这时类型推导对于编译器来说有些困难。例如:
def fac(n: Int) = if (n < 0) 1 else n * fac(n - 1)
编译器无法推断n * fac(n - 1)最终会是什么类型。

默认参数

在Scala中,你可以为参数设定默认值。当调用该函数时,如果没有为某个参数指定值,那么函数会以设定好的默认值来运行,例如:
def sum(a: Int = 1,b: Int = 2, c: Int = 3) = {
println("a: " + a)
println("b: " + b)
println("c: " + c)
a + b + c
}
在调用的时候,你可以指定自己想要的a、b和c的值,比如:
sum(10,20,30)
会得到60,也可以只给0个或1个或2个参数,当参数不够的时候,默认参数会从后往前逐个应用进来。下面演示一下,这个机制还是很好理解的:

在scala函数中,你也可以使用带名参数,就像下面这样:

要注意参数名要写的和定义时一样,这种方式一般是用来保证参数正确的得到赋值,如果对函数的定义不了解,还不如不写。以下几种写法都是正确的:
sum(10,b = 20, 30) //60
sum(10,b = 20) //33
sum(10,c = 20) //32
这样写也对:
sum(10,c = 20,b = 30) //60
但是最好不要这样,会导致混乱,参数的先后顺序建议按照定义的先后顺序写。

变长参数

有时候,在定义的时候不能确定函数的参数个数或者为了使函数具有更好的通用性,可以定义变长参数。比如:
     def sum (args: Int*) = {
var result = 0
for (arg <- args) result += arg
result
 }
这样就可以使用任意多的参数了。比如这样调用:
val s = sum(1, 2, 3, 4, 5) //15
参数可以看成一个Seq类型。但是你不可以直接传给sum一个已有的序列,比如:
val s = sum(1 to 5)
会提示一个类型不匹配的错误:

可以这样来使刚才的做法变得可行:
val s = sum(1 to 5:_*)
运行如下:

这样用:_*来告诉编译器把这个参数当做参数序列来处理。编译器就会不追究了。在scala中这样的奇怪符号还有很多,以后有机会再介绍了。
在一些场景中,这样的语法是必须要用到的。
def reSum(args Int*): Int = {
if (args.length == 0) 0
else args.head + reSum(args.tail:_*)
}
在这个递归求和函数中.head表示首个元素,.tail表示除了首个元素,其余的元素,返回的也是一个Seq类型。所以需要用:_*来转换。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值