目录
1.普通方法定义及注意细节
/**
* 1.方法定义
* 1)方法体中最后返回值可以使用return,如果使用了return,那么方法体重的返回值类型一定要指定
* 2)如果方法体中没有return,默认将方法体中最后一行计算结果当做返回值返回,方法体的返回值类型可以省略,scala会自动推断返回类型
* 3)定义方法传入的参数一定要指定类型
* 4)方法的方法体如果可以一行搞定,那么方法体的"{......}"可以省略
* 5)如果定义方法时,省略了方法名称和方法体之间的"=",那么无论方法体最后一行计算的结果是什么,都会被丢弃,返回unit空值
* 6)定义方法用 def 声明
*/
object Function {
def main(args: Array[String]): Unit = {
// 1)方法体中最后返回值可以使用return,如果使用了return,那么方法体中的返回值类型一定要指定
// 3)定义方法传入的参数一定要指定类型
def max(a : Int,b : Int): Int = {
if (a > b){
return a
}else{
return b
}
}
// 2)如果方法体中没有return,默认将方法体中最后一行计算结果当做返回值返回,
// 法体的返回值类型可以省略,scala会自动推断返回类型
def max(a : Int,b : Int) = {
if (a > b){
a
}else{
b
}
}
// 5)如果定义方法时,省略了方法名称和方法体之间的"=",
// 那么无论方法体最后一行计算的结果是什么,都会被丢弃,返回unit空值
def max(a : Int,b : Int) {
if (a > b) a else b
}
//方法名与方法体中间没有=,则返回unit空值,而且调用函数需要在打印语句中,不能赋值给变量或常量
//println(max(100,20))
// 4)方法的方法体如果可以一行搞定,那么方法体的"{......}"可以省略
def max(a : Int,b : Int) = if (a > b) a else b
val result : Int = max(100,200)
println(result)
}
}
2.递归函数
/**
* 2.递归方法
* 递归方法要显示的声明函数的返回值类型,否则scala无法确定具体的返回值类型,会报错
*/
// def fun(num : Int)={...}如果方法体中进行递归的话,这种声明方式就是错的,没有显示声明返回值类型
def fun(num : Int) : Int = {
if (num == 1){
1
}else{
num*fun(num - 1)
}
}
println(fun(5))
3.参数有默认值的方法
/**
* 3.参数有默认值的方法
*/
def fun(a:Int=10,b:Int=20):Int = {
a+b
}
println(fun())//参数有默认值的方法可以直接调用,不用传参数
println(fun(100))//也可以传入参数,这里是给a传入参数,把a的默认值覆盖掉
println(fun(b = 200))//如果想给b传入参数的话,就要标明是给b传的
println(fun(100,200))//也可以直接给方法中所有的参数赋值
4.可变长参数的方法
/**
* 4.可变长参数的方法
* 如果一个类型的参数需要传多个,那么可以在参数类型后面加*,表示可变长,如下:
*/
def fun(s:String*)={
//以下四种方式都可以遍历打印可变长字符串,其中一些细节需要注意:
//用foreach遍历,foreach里面传入的是方法,有 => 符号的是匿名函数,这里是传入了一个匿名函数
s.foreach(elem =>{println(elem)})
//如果匿名函数中只有一个参数的话,并且参数只用了一次的话,那么可以省略参数名,用 _ 代替
s.foreach(println(_))
//println本身就是个方法,如果只有一个参数,那么可以不用给参数,直接println也可以打印
s.foreach(println)
//中规中矩的for循环来遍历打印
for (elem <- s){
println(elem)
}
}
fun("nihao","wohao","a")
5.匿名函数
/**
* 5.匿名函数(scala中可以理解为函数等价于方法)
* 有“ => ”符号就是匿名函数,多用于方法的参数是函数时,常用匿名函数
*/
//1.匿名函数声明,但没有名字,调用不了
(a:Int,b:Int)=>{
a+b
}
//2.用一个函数名接收一下匿名函数,但其实匿名函数多用于方法的参数是函数时,很少单独声明一个匿名函数进行调用
def fun = (a:Int,b:Int)=>{
a+b
}
println(fun(100,200))
//3.匿名函数一般用于方法的参数是函数时,如:s.foreach(elem =>{println(elem)})
6.嵌套函数
/**
* 6.嵌套方法
* 在方法内调用方法中声明的方法,即嵌套方法
*/
def fun(num:Int)= {
def fun1(a:Int) : Int ={
if (a == 1){
1
}else{
a*fun1(a-1)
}
}
//在方法内调用方法中声明的方法,即嵌套方法
fun1(num)
}
println(fun(5))
7.偏应用函数
/**
* 7.偏应用函数
* 某些情况下,方法中的参数非常多,调用这个方法非常频繁,
* 并且每次调用这个函数,只有固定的某个参数变化,其他参数都不变,那么可以定义偏应用来实现
*/
def showLog(data:Date,log:String) = {
println(s"data is $data , log is $log")
}
val date = new Date()
//没有定义偏应用函数时,date是固定的,每次调用都要传入date
showLog(date,"a")
showLog(date,"b")
showLog(date,"c")
//定义偏应用函数,参数需要变的用 _ 代替
def fun = showLog(date,_:String)
//调用偏应用函数
fun("aaaa")
fun("bbbb")
fun("cccc")
8.高阶函数
(1)方法的参数是函数
//1.方法的参数是函数(用的最多)
//一般用于spark中,拿到了数据,我们可以传入函数来达到我们的需求
def fun(a:Int,b:Int) = {
a+b
}
//定义fun1,参数为函数
def fun1(f:(Int,Int)=>Int,s:String):String = {
val i : Int= f(100, 200)
i+"#"+s
}
//调用fun1的方式有两种:
//(1)传入写好的函数
val result = fun1(fun,"scala")
//(2)传入匿名函数
val result1 = fun1((a:Int,b:Int)=>{a*b},"scala")
println(result)
println(result1)
(2)方法的返回值类型是函数
//2.方法的返回值类型是函数
//<必须要显示的写出方法的返回值类型,或者加 _ 就可以不显示地声明方法的返回值类型>
def fun(s:String):(String,String)=>String = {
def fun1(s1:String,s2:String):String = {
s1+"~"+s2+"#"+s
}
fun1 //fun1 == return fun1 ,scala中可以省略return,默认选用最后一行的值作为返回值。
//这里如果写成 fun1 _ ,就可以不用声明返回值类型,_ 的作用是强制返回fun1的返回值类型。
}
//调用fun()函数
println(fun("sacala")("a","b"))
(3)方法的参数和返回值类型都是函数
//3.方法的参数和返回值类型都是函数
def fun(f:(Int,Int)=>Int):(String,String)=>String = {
var i: Int = f(1, 2)
def fun1(s1:String,s2:String):String = {
s1+"#"+s2+"$"+i
}
fun1
}
println(fun((a,b)=>{a+b})("hello","world"))
9.柯里化函数
/**
* 9.柯里化函数
*/
def fun(a:Int,b:Int)(c:Int,d:Int) = {
a+b+c+d
}
println(fun(1,2)(3,4))