函数方法和函数参数
函数方法
也可以使用def关键字来定义有名字的函数。在Scala 中,使用关键字def 定义函数,其语法格式如下:
def 函数名(参数1:数据类型,参数2:数据类型):函数返回类型= { 函数体 }
这种方式,通常是用在一个类中,用来定义方法用的。例如,下面定义方法add:
// 定义方法add def add(x:Int, y:Int):Int = { println("这是一个对两个整数进行求和的函数") x + y } // 通过函数名来调用函数(方法) add(3,5)
有的方法可以有返回值。在Scala中,函数体的最后一行表达式的值,就是返回值。下面定义一个有返回值的方法:
def func1(name:String, age:Int) : String ={ println("name=> " + name +"\t age=> " + age) "欢迎" + name + "光临, 您的年龄是 => " + age // 函数的最后一行是返回值 } func1("张三", 23)
有的方法无返回值。下面定义一个无返回值的方法:
def func2(): Unit ={ println("这个函数执行没有返回值") } func2()
有的方法比较简单,只有一行执行代码,可以写在一行上,称为"单行函数",如下所示:
def printMsg(name:String) = println("Hello, " + name +", welcome happy day!!!") printMsg("李四")
函数参数
函数定义时指定的参数称为“形参”,函数被调用时实际传入的参数称为“实参”。默认在函数调用时,实参和形参是按顺序一一对应的,否则有可能出现错误。如下代码所示:
def func3(name:String, age:Int) : String = { println("name=> " + name + "\t age=> " + age) "欢迎" + name + "光临, 您的年龄是 => " + age } func3("张三",23) // OK // func3(23,"张三") // 出错,类型不匹配
为了避免这种错误,可以在调用函数时指定参数名称(这称为名称参数),这样就不必一定要按顺序传入实参了。如下代码所示:
func3(age=23, name="张三") // OK
也可以混用未命名参数和名称参数,只要那些未命名的参数是排在前面的即可:
func3("李四",age=23)
也可以在定义函数时指定默认参数。如果指定了默认参数,那么在调用函数时如果没有为该参数传入实参值,则默认传入的是默认参数。如下所示:
func3(age=23) // 出错,参数name未给值
下面的代码在定义函数时,为形参指定了默认值,如下:
def func5(name:String="匿名", age:Int=18) : String ={ println("name=> " + name +"\t age=> " + age) "欢迎" + name + "光临, 您的年龄是 => " + age } // func5(age=23) func5()
Scala在定义函数时允许指定最后一个参数可以重复(变长参数),从而允许函数调用者使用变长参数列表来调用该函数。使用可变参数的语法如下:add(a:Int,b:Int,c:Int*)。Scala中使用"*"来指明该参数为变长参数。当它被定义为Int*时,则必须将所有参数作为Int传递。可以将其他参数与可变长度参数一起传递,但是可变长度参数应该是参数列表中的最后一个。函数不能接受两个可变长度参数。
请看下面的代码:
def echo(name:String, age:Int, args:String*) = { println(name) println(age) for (arg <- args) println(arg) } echo("张三", 23, "hello", "123", "123", "456")
练习:请定义一个名为add的函数,可以实现对任意多个整数的求各计算。
def add(values:Int*)={ var sum =0; for (value <- values){ sum = sum+value } sum } val sum = add(1,2,3,4,5,6,7,8,9) println(s"所有参数的和是: $sum")
在函数内部,变长参数的类型,实际为一个数组,比如上例的String* 类型实际上为Array[String]。然而,如果试图直接传入一个数组类型的参数给这个参数,编译器会报错:
val arrs = Array("hello","吃了吗") // echo("张三",23,arrs) // 出错
为了避免这种情况,可以通过在变量后面添加_*来解决,这个符号告诉Scala编译器在传递参数时逐个传入数组的每个元素,而不是数组整体。如下所示:
val arrs = Array("hello","123","123","456") echo("张三",23, arrs:_*)