目录
方法和函数
说明:在Scala中既有方法也有函数,大多数情况下,他们没有区别,作为初学者暂时不用明确区分。一般情况下方法的类型为具体一个返回值类型,可以省略不写。而函数的类型为:参数类型 => 返回值类型 ,也可以省略不写,在后边的代码中会体现这个特点。
方法的定义
def max(a:Int,b:Int):Int={
if(a>b) return a else return b
}
println(max(1, 3))
- 方法用def来定义
- 方法体中最后的返回值可以使用return,如果使用了return,那么方法体的返回值类型一定要定义
- 如果方法体中没有return,默认将方法体中的最后一行计算的结果当做返回值返回,方法体的返回值类型可以省略(自动推断)
- 定义方法传入的参数一定要指定类型
- 如果方法体为一行代码,方法的定义也可以简写
比如:
def max(a: Int, b: Int): Int = if (a > b) return a else return b
- 如果定义的方法没有返回值(Unit)也可以省略方法名称和方法体之间的“=”,要注意,省略了等号,不管有没有返回值都不会反回任何内容。
递归方法
定义方法递归调用时必须显示的定义出函数返回值,否则其无法推断,不能通过编译
def fun(num: Int): Int = {
if (num == 1) 1 else num * fun(num - 1)
}
方法的默认参数
Scala支持定义方法时对参数设置默认值。调用时输入参数则使用输入的参数,空参则使用默认值
def sum(a: Int = 10, b: Int = 20) = {
a + b
}
println(sum())//空参
println(sum(100,200))//覆盖
println(sum(100))//覆盖a
println(sum(b=200))//覆盖b
可变参数的方法
与java相同,scala同样有参数可变的需求
def sum(num: Int*): Int ={ // * 号代表此参数可以有多个,但是传入的值类型必须相同。
var sum = 0
for(i <- num){
sum += i
}
sum
}
嵌套方法
方法的嵌套类似if、for的嵌套,以下列子为:求5的阶乘。
def fun1(num:Int): Int ={
def fun2(a:Int,b:Int): Int ={
if(a==1){
b
}else{
fun2(a-1,a*b)
}
}
fun2(num,1)
}
匿名函数
匿名函数定义方法如下,一般在作为参数传入其他方法或函数中只使用一次的情况中使用,类似java中的匿名内部类。
(a:String) => {
println(a)
}
当然匿名函数也可以有引用
val stringToUnit: String => Unit = (a: String) => {
println(a)
}
stringToUnit("Dongcc")
偏应用函数
偏应用函数一般用来解决一个方法中的参数非常多,并且有部分参数总是不发生变化(比如下面第一段代码中,“现在是”这个参数每次都不需要变化)而每次调用这个方法总是需要传入这些不变的参数的问题。此时可以使用偏应用函数来简化这个过程(见第二段代码)。
def showDate(s:String,date:Date): Unit ={
println(s"$s : $date")
}
showDate("现在是",new Date())
Thread.sleep(1000)
showDate("现在是",new Date())
Thread.sleep(1000)
showDate("现在是",new Date())
为showDate方法定义偏应用函数showDate2
val showDate2: Date => Unit = showDate("现在是", _: Date)
showDate2(new Date())
高阶函数
在高阶函数中,有三种表现形式
方法的参数是函数
def fun(f:(Int,Int)=>Int,s:String): Unit ={
val i = f(100, 2)
println(s"100 和 2 的 $s 是 $i")
}
//这里传入一个匿名函数作为参数
fun((a:Int,b:Int)=>{a+b},"和")
方法的返回是函数
这里用一个场景说明以下代码,假设有这样一个场景,我们需要按照用户的不同情况来决定下一步应该使用什么样的函数,比如以下代码表示的是当输入年龄信息为18岁以下时,返回不可参加工作的函数,而18岁及以上时返回可以参加工作的函数。
返回的函数也可以是匿名函数,return可以省略不写,新版本中fun方法的返回值类型也可以不写。
def fun(a: Int): (String) => Unit = {
if (a >= 18) {
def fun1: String => Unit = (s: String) => {
println(s"$s 成年了,可以参加工作了")
}
return fun1
} else {
def fun2: String => Unit = (s: String) => {
println(s"$s 未成年,不可以参加工作")
}
return fun2
}
}
val fun1: String => Unit = fun(13)
fun1("锤锤")
val fun2: String => Unit = fun(22)
fun2("铁蛋")
//因为返回值是一个函数,所以也可以直接调用返回值
fun(18)("Dongcc")
注意:在2.10版本之前,方法的返回值类型应该显示声明
方法的参数和返回都是函数
def fun(f: (Int, Int) => Int): (String) => Unit = {
val i = f(100, 200)
(s: String) => {
println(s + i)
}
}
val result = fun((a: Int, b: Int) => {
a + b
})
result("100+200=")
//也可以简写成
fun((a,b)=>{a+b})("100+200=")
柯里化函数
柯里化函数其实在高阶函数中我们已经见过他的形式
比如上边例子的最后一行:fun((a,b)=>{a+b})("100+200=")
def fun(a:Int,b:Int)(c:Int,d:Int)={
a+b+c+d
}
fun(1,2)(3,4)
学习下一节