1. 如果函数体只有一行代码,则可以不用写{},比如
- def print(x: Int) = println(x)
一行上的多条语句用分号隔开,则只有第一句属于方法体,例如
- def printWithValue(x: Int) : String= println(x); "ABC"
上面的代码报错,因为,printWithValue的方法体只有一句代码println(x),而它结果值是Unit,因此指定printWithValue返回String,出现类型返回错误。如果将两条语句包在一起,则正确
- def printWithValue(x: Int) : String= {println(x); "ABC"}
2.无参函数,在调用时,不需要写(),直接写函数名即是方法调用。则代码中写print和print()都是方法调用
- def print() = println(100)
3. 如果方法明确的指定了返回值的类型,则必须在返回值类型后加等于号,否则可以不加也可以加
- def noReturn() = {
- println("100");
- }
也可以写成:
- def noReturn() {
- println("100");
- }
如下写法是不正确的:
- def noReturn():Unit {
- println("100");
- }
必须写成:
- def noReturn() :Unit = {
- println("100");
- }
因此,好的习惯是不论有无返回值,都加=
4.默认函数值,必须出现在最后,即带有默认值的参数后不能再有不带默认值的参数了
- def add(a: Int, b: Int = 20, c: Int = 30): Int = {
- a + b + c
- }
下面的写法,不报错,但是调用add(100)则报错
- def add(a: Int = 20, b: Int, c: Int = 30): Int = {
- a + b + c
- }
5. 变长参数,使用T*表示
- def sum(elems: Int*) : Int = {
- var sum = 0;
- elems.foreach(elem => sum += elem)
- sum
- }
下面的写法则报错:
- def sum(elems: Int*) : Int = {
- var sum = 0;
- elems.foreach(_ => sum += _)
- sum
- }
提示,sum += _不正确
- Error:(61, 31) missing parameter type for expanded function ((x$2) => sum.<$plus$eq: error>(x$2))
- elems.foreach(_ => sum += _)
- ^
如下写法是正确的,使用_指代循环的变量,简单的写法:
- def sum(elems: Int*) : Int = {
- var sum = 0;
- elems.foreach(sum += _)
- sum
- }
6. 方法抛异常,无需检查Checked Exception
- def exceptionProcessing() {
- try {
- throw new Exception("error");
- } catch {
- case e:IllegalArgumentException => println("IAE" + e.getMessage)
- case e: NullPointerException => println("NPE" + e.getMessage);
- case e: Exception => throw e //如果是Exception,则重新抛出
- }
- }
7. 带有多个(参数)的函数,柯力化
- def addXY(x:Int)(y:Int) : Int= {
- x + y
- }
通过如下调用:addXY(1)(2)
8. 函数赋值
- def addXY(x:Int)(y:Int) : Int= {
- x + y
- }
- val copyOfAddXY = addXY(1)(_)
- println(copyOfAddXY(3))
结果是4,这表示部分应用函数,如果不加(_)则是不正确的
9,部分应用函数:
- def substract(a: Int, b: Int, c: Int): Int = {
- a + b - c
- }
则如下的第一个赋值是正确的,剩下的两个都不正确,
- var func1 = substract(_,_,_) ///正确
- println(func1(1,5,3))
- func1 = substract(2,_,_) //提示:Wrong number of parameters, expected
- println(func1(8,3));
- func1 = substract(3,_,9)//提示:Wrong number of parameters, expected
- println(func1(100))
10. 闭包
- def closure(x :Int) :Int => Int ={
- def sum(y:Int) :Int = {
- x + y //x is not in the scoped of the
- }
- sum
- }
调用closure(10)(100),注意Int=>Int是函数sum的类型,即输入为Int,输出也为Int
11.
- def myValue = {
- val a = 10
- a + 10
- }
- val myValue = {
- val a = 10
- a + 10
- }
12
- def myFunc() = {
- val a = 10;
- a + 10
- }
println(myFunc())为什么打印20,因为myFunc没有指明返回值的类型,那就默认是Unit?这个理解是错误的,Scala的函数定义也可以自动推导函数的返回类型,一个函数是否有返回值,看参数列表()和方法体{}之间是否有等号,有等号,则把
最后一个语句的返回值作为函数的返回值(尽管没有显式指定函数的返回值),如果没有使用等号,那么函数一律返回Unit