Scala函数-随堂笔记(持续更新)

it2023-02-19  83

Scala函数

Java LambdaScala函数定义函数调用 参数传递命名参数参数缺省值参数个数未知 匿名函数函数作参数函数作返回值课堂小测柯里化Currying隐式参数隐式函数模式匹配部分函数偏函数

Java Lambda

函数式接口:

一种只含有一个抽象方法声明的接口可以使用匿名内部类实例化函数式接口的对象通过Lambda表达式可以进一步简化代码

Lambda语法:

(parameters) -> expression (parameters) -> { statements; }

Scala函数定义

def 函数名([参数列表]):[返回值]={ 函数体 return [表达式] }

实例:

def square(x:Int):Int={ println(x) x * x } def sayHello(x:String):Unit={ println("Hello "+x) }

函数调用

函数名(参数列表)

参数传递

传值调用 call-by-value 传值调用时,参数只在调用时计算一次,后续重复使用计算结果

def square(x:Int):Int={ println(x) //3 x * x } square(1+2) // 先计算1+2

传名调用 call-by-name 传名调用时,参数在调用时不会计算,只有真正用到参数时才计算

def square(x:=>Int):Int={ println(x) //计算1+2 x * x //计算(1+2)*(1+2) } square(1+2) //不计算

命名参数

通常情况下,传入参数与函数定义的参数列表一一对应,而命名参数允许使用任意顺序传入参数

def showMsg(name:String,age:Int)={ println("Hello "+name+" age:"+age) } showMsg("kb09",3) showMsg(age=18,name="zhangsan")

参数缺省值

Scala函数允许指定参数的缺省值,从而允许在调用函数时不指明该参数

def printName(first:String="John",last:String="Smith")={ println(first+" "+last) } printName() //输出"John Smith"

参数个数未知

def showMsg2(name:String,str:String*)={ println(name) for (s<-str){ print(s+"\t") } } showMsg2("kb09","zhangsan","lisi","wangwu")

匿名函数

匿名函数指不含函数名称的函数

匿名函数的定义:

(参数列表)=>{函数体} //如果函数体包含多条语句,应使用{}包含

匿名函数调用实例:

(a:Int, b:Int)=>a+b //用变量去接受匿名函数 val aa=(a:Int, b:Int)=>a+b val bb=aa println(aa(1,3)) //输出4 println(bb(3,5)) //输出8

函数作参数

def fun(a:Int,b:Int)=a+b def fun1(a:Int,b:Int)=a-b def fun2(a:Int,b:Int)=a*b def funTest(f:(Int,Int)=>Int,s:String)={ val resValue = f(10,20) s+resValue } println(funTest(fun, "SUM:")) //30 println(funTest(fun1, "DIFF:")) //-10 println(funTest(fun2, "MULTI:")) //200 println(funTest((a:Int,b:Int)=>a*2+b*3, "SELFMADE:")) //80

函数作返回值

def funTest2():(String,String)=>String={ def fun3(str1:String, str2:String):String={ str1+"||"+str2 } fun3 } var strValue=funTest2()("aa","bb") println(strValue) //输出"aa||bb"

课堂小测

输出一个指定数的阶乘(递归思路)

def jc(a:Int)={ if (a==1) 1 else a*jc(a-1) } println(jc(8)) //40320

柯里化Currying

方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为柯里化

//单参数列表 def modN(n: Int,x: Int) = ((x % n) == 0) //多参数列表 def modN(n: Int)(x: Int) = ((x % n) == 0) //新函数接收剩余的参数列表作为其参数 def f1(x: Int) = modN(10)(x) def f2(n: Int) = modN(n)(10) def f3 = modN(10)(_) def fun(a:Int,b:Int,c:Int,d:Int)=a+b+c+d def fun1(a:Int,b:Int)(c:Int,d:Int)=a+b+c+d def fun2(a:Int)(b:Int)(c:Int)(d:Int)=a+b+c+d println(fun2(1)(2)(3)(4))

隐式参数

方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记

implict只能修改最尾部的参数列表,应用于其全部参数Scala可自动传递正确类型的隐式值通常与柯里化函数结合使用 //隐式参数 implicit var a:Int=10 implicit var str:String="hello" def fun(a:Int,b:Int)(implicit c:Int):Int={ a+b+c } def fun1(a:Int,b:Int)(implicit c:Int=5,str:String):Int={ println(str) a+b+c } //优先级:传参>隐式参数>默认 println(fun1(1, 2)(str="abc"))

隐式函数

隐式函数也称隐式转换,使用implicit修饰的函数

类型转换 implicit def double2Int(x:Double)=x.toInt val i:Int=3.5 类型增强 implicit def bool2Int(x:Boolean)=if(x) 1 else 0 println(1+true)

更多隐式实例:

package Date1022 import Date1022.implicitpack._ class demo2{} object demo2 { def main(args: Array[String]): Unit = { // val res1 = sum(10,10) // println(res1) // val res2 = showMsg("张三") // println(res2) // val res3:Int=3.5 // println(res3) // val res4:Int="20" // println(res4) val dm =new demo2 println(dm.multi(4, 6)) println(dm.sum(10, 90)) println(dm.divide(30, 4)) } def sum(a:Int,b:Int)(implicit c:Int):Int=a+b+c def showMsg(name:String)(implicit s:String):String=s+name //def multi(a:Int,b:Int)(implicit c:Int):Int=a*b*c }

隐式类

package Date1022 class demo3{} import Date1022.implicitpack._ object demo3 { //隐式类的使用,与demo3相关的两个隐式类全部在Implicitpack中 //创建好demo3对象中,虽然demo3中没有一个方法,但是因为隐式 //类中是有好多方法的,因些demo3对象后就可以使用这些方法 //隐式类的主要作用就是类对象中没有的方法可以直接被类对象调用 def main(args: Array[String]): Unit = { val dm3=new demo3 dm3.aa("k") println(dm3.bb(19)) println(dm3.add(2, 5)) println(dm3.aa("zhangsan", "123")) } }

隐式包

package Date1022 object implicitpack { implicit val a:Int=10 implicit val b:String="b" implicit def doubletoint(value:Double): Int =value.toInt implicit def stringtoint(value:String): Int =Integer.parseInt(value) implicit class NumOperation(demo:demo2){ def multi(a:Int,b:Int)={ a*b } def sum(a:Int,b:Int)={ a+b } def sub(a:Int,b:Int)={ a-b } def divide(a:Int,b:Int)={ a/b } } implicit class demo3_implicit(demo:demo3){ def aa(a:String): Unit ={ println(a+a) } def bb(num:Int): String ={ if (num%2==0) "偶数" else "奇数" } def add(a:Int, b:Int): Int ={ a+b } } implicit class demo3_implicit2(demo:demo3){ def aa(name:String,pwd:String):Boolean={ if (name=="张三" && pwd=="123456") true else false } } }

模式匹配

package Date1022 import java.io.FileNotFoundException class Person case class Teacher(name:String,subject:String) extends Person case class Student(name:String,classroom:Int) extends Person case class Worker(name:String,worktype:String) extends Person case class Stranger() extends Person object demo1 { def matchMarks(name:String,marks:Int):Unit={ marks match { case _ if marks >= 90 => println("High Distinction") case _ if marks >= 80 => println("Distinction") case _ if marks >= 70 => println("Good") case _ if marks >= 60 => println("Normal") case _a => println("Fail, score:" + _a) //case _marks => println(s"$name's marks are "+_marks) } } def matchException(e:Exception):Unit=e match { case e:IndexOutOfBoundsException => println("下标越界") case e:FileNotFoundException => println("找不到指定文件") case e:NullPointerException => println("空指针异常") case _:Exception => println("程序异常") } def matchArr(arr:Array[String]): Unit ={ arr match { case Array("Jessica", _*) => println("Hello") case Array(girl1, girl2, girl3) => println(girl1+" "+girl2+" "+girl3) case _ => println("GoodBye") } } def matchPerson(p:Person): Unit ={ p match { case p:Teacher => println("你是"+p.name+"老师,你教"+p.subject) case p:Student => println("你是"+p.name+"学生,你的教师在"+p.classroom) case p:Worker if p.worktype=="修理工" => println("你是修理工") case p:Stranger => println("我不认识你") } } val map=Map("zs"->"a","ls"->"b","ww"->"c") def matchMap(name:String):Unit={ var score=map.get(name) score match{ case Some(score)=>println(name+"的成绩为"+score) case None=>println(s"没有$name 的成绩") } } def main(args: Array[String]): Unit = { //matchMarks("zhangsan",57) //matchException(new IndexOutOfBoundsException) //val arr = Array("Jessica","Lily","Sofia","Lucy") //matchArr(arr) //val teacher = Teacher("张三","数学") //matchPerson(teacher) matchMap("zl") } }

部分函数

def showMess(title:String,content:String,num:Int):Unit={ println(title+" "+content+" "+num) } showMess("警告","",1) val title="警告:" def showWaterAlter =showMess(title,_:String,_:Int) showWaterAlter("当前水位",12) def add(a:Int,b:Int,c:Int)={ a+b+c } val a=5 def addadd=add(a,_:Int,_:Int) println(addadd(4, 3))

偏函数

def funPartitional:PartialFunction[String,Int]={ case "hello" => 1 case "world" => 2 case _ => 0 } println(funPartitional("world")) val words=List("world","hello","gree","kb09") words.collect(funPartitional).foreach(println) words collect funPartitional foreach println println(Array(1, 2) collectFirst {case x if x % 2 == 0 => x + 100}) def funTuple:PartialFunction[Char,(Char, Int)]={ case 'A'=>('A',1) case 'B'=>('B',1) case _=>('X',1) } val tuple:(Char,Int)=funTuple('A') println(tuple) var chars=List('A','B','C','D') var tuples:List[(Char,Int)]=chars.collect(funTuple) tuples.foreach(x=>println(x._1,x._2)) def fun2:PartialFunction[Any,Int]={ case i:Int=>i case _=>0 } var list=List('a','c',2,2.5,90) list.collect(fun2).foreach(println)
最新回复(0)