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

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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值