Scala_方法和函数
目录
方法的定义
def functionName([参数列表]) : [return type] = {
function body
return []
}
- 如果没有=和{}包裹的方法体,那么该方法被隐式申明为抽象(abstract)方法,包含它的类就是抽象类。
abstract class Test{
def hi(x : Int):Int
def he(x : Int){x + 1}
}
- 当输入相同类型的参数个数无法确定时,可以使用变长参数,如:def sum(args : Int*) = {for(arg <- args) println(arg)}。
- 如果方法体直接包裹在了花括号里面,而没有使用=连接,则方法的返回值就是(),其类型就是Unit,这样的方法就被称之为过程。可以为过程指定返回值类型为Unit,此时方法体中有return语句,方法返回值任然是Unit。
- 不写明返回值的类型,程序会自行判断,最后一行代码的执行结果为返回值。
函数
Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。
Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
定义方式
class Test1{
def met(x : Int) = x + 10
val fun = (x : Int) => x + 10 // 匿名函数 (x : Int) => x + 10 赋值给变量 fun
}
- 方法是一个以def开头的带有参数列表(可以无参数列表)的一个逻辑操作块,这正如object或者class中的成员方法一样。
- 函数是一个赋值给一个变量(或者常量)的匿名方法(带或者不带参数列表),并且通过=>转换符号跟上逻辑代码块的一个表达式。=>转换符号后面的逻辑代码块的写法与method的body部分相同。
- 方法名意味着方法调用,函数名只是代表函数自身。
- 方法可以没有参数列表页可以是空的参数列表。
- 函数必须设置参数列表,可以是空的参数列表,但一定要设置。
方法和函数的相互转换
- 把 x => func(x) 简化为 func _ 或 func(_) 的过程称为函数转换成方法
- 把 func(_)或 func _ 展开为 x => func(x) 的过程为方法转换成函数
递归函数优化
正常递归函数会创建多个栈导致栈溢出,优化后不会创建新的栈,会使用前个函数的栈空间
通过注解优化递归函数(@annotation.tailrec),优化条件是最后一个语句是递归调用的函数,否则报错
def dgui(n: Int,x:Int): Int = {
if( x >= 1 ) n * dgui(n,x-1)
else 1
}
@annotation.tailrec
def dguiTailrec(n: BigInt, acc: BigInt): BigInt = {
if(n <= 1) acc
else dguiTailrec(n-1, acc * n)
}
高阶函数
高阶函数就是使用其他函数作为函数的参数,或者使用其他函数作为函数的输出结果
test方法有两个参数,第一个参数是名为func的一个函数,该函数有一个String类型的参数,并且其返回值是Unit;第二个参数是String类型的cont
test的方法体是将第二个参数cont作为第一个参数即函数func的参数;test方法的返回值是Unit
Scala 函数柯里化(Currying)
柯里化指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
def add(x:Int,y:Int)=x+y
柯里化
def add(x:Int)(y:Int) = x + y
函数的currying化行为本质上也是一个高阶函数:接受现有的函数,返回新函数。
这个例子就是对上一个例子的currying化操作。传入第一个参数后返回一个函数,然后再传入第二个参数,完成第二个函数。这样就讲一个高阶函数拆解成两个一阶函数。
闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
var factor = 3
val multiplier = (i:Int) => i * factor