scala中的case非常强大,既可以匹配值,匹配类型,匹配集合,匹配class,匹配object。
--case匹配值
scala> def bigData(data: String){
| data match{
| case "Spark" => println("Wow!")
| case "Hadoop" => println("Ok")
| case _ => println("Others") --下划线代表其他情况,java每行要写break,这里不用
| }
| }
bigData: (data: String)Unit
scala> bigData("Spark")
Wow!
scala> bigData("Hadoop")
Ok
scala> bigData("Flink")
Others
scala> def bigData(data: String){
| data match{
| case "Spark" => println("Wow!")
| case "Hadoop" => println("Ok")
| case _ if data == "Flink" => println("Cool") --可以写if进行判断
| case _ => println("Others")
| }
| }
bigData: (data: String)Unit
scala> bigData("Flink")
Cool
scala> bigData("GreenPlum")
Others
scala> def bigData(data: String){
| data match{
| case "Spark" => println("Wow!")
| case "Hadoop" => println("Ok")
| case data1 if data == "Flink" => println("Cool " + data1) --赋值data1=data
| case _ => println("Others")
| }
| }
bigData: (data: String)Unit
scala> bigData("Flink")
Cool Flink
--------------------------------------------------------------------
--case不仅可以匹配值,也可以匹配类型。
scala> /
scala> import java.io._
import java.io._
scala> def exception(e:Exception){
| e match{
| case x:FileNotFoundException => println("File not Found. "+x) --x是变量,可以随便定义,x接收e的值
| case _:Exception => println(e)
| }
| }
exception: (e: Exception)Unit
scala> exception(new FileNotFoundException("Oh!"))
File not Found. java.io.FileNotFoundException: Oh!
--------------------------------------------------------------------
--case匹配集合
scala> /
scala> def data(array: Array[String]){
| array match{
| case Array("Scala") => println("Scala")
| case Array(var1,var2,var3) => println(var1+" "+var2+" "+var3) --匹配长度为3的数组
| case Array("Spark",_*) => println("Spark...") --匹配第一个元素为Spark
| case _ => println("Unknown")
| }
| }
data: (array: Array[String])Unit
scala> data(Array("Scala"))
Scala
scala> data(Array("Spark"))
Spark...
scala> data(Array("Spark","Scala","Kafka"))
Spark Scala Kafka
scala> data(Array("Spark","Scala"))
Spark...
--------------------------------------------------------------------
--case class 样例类
case object有时也这样用
case class相当于java中的been,参数被封装为消息,一般不会改变。默认情况下只有getter。
里面默认情况下是只读成员,特别适合并发编程时候的消息通信
一般只定义属性,由scala编译的时候自动生成getter和setter,但是它没有其他的方法。
在接收参数的时候不需要val/var定义,此时scala会自动用val修饰,你也可以手动去写var,但var代表可以修改里面的内容,这没有必要,而且也不符合java been或者消息通信体的设计的目的。
scala> case class Person(name: String)
defined class Person
scala> Person("Spark")
res217: Person = Person(Spark)
在内部工作的时候,会生成当前case class的半生对象,会自动生成object,会有apply方法。
参数Spark会作为半生对象的apply方法的参数,apply接收这个参数后,会帮助我们构建实际的case class对象。
scala> class Person
defined class Person
warning: previously defined object Person is not a companion to class Person.
Companions must be defined together; you may wish to use :paste mode for this.
scala> case class Worker(name: String,salary: Double) extends Person
defined class Worker
scala> case class Student(name: String,score: Double) extends Person
defined class Student
scala> def sayHi(p: Person){
| p match{
| case Worker(name,salary) => println("I am a Worker: "+name+salary)
| case Student(name,score) => println("I am a Student: "+name+score)
| case _ => println("Unknown")
| }
| }
sayHi: (p: Person)Unit
scala> sayHi(Worker("LeiFeng",3000.65))
I am a Worker: LeiFeng3000.65
scala> sayHi(Student("Lucy",20.5))
I am a Student: Lucy20.5
case class在工作的时候,会生成很多的实例,每次工作都会生成实例。
Spark源码中:
worker发送心跳给master,master接收心跳,通过case Heartbeat判断workerId有没有值。
--Master.scala
override def receive: PartialFunction[Any, Unit] = {
...
case Heartbeat(workerId, worker) => {
idToWorker.get(workerId) match {
case Some(workerInfo) => --idToWorker.get(workerId)能返回workerInfo
workerInfo.lastHeartbeat = System.currentTimeMillis()
case None =>
if (workers.map(_.id).contains(workerId)) {
logWarning(s"Got heartbeat from unregistered worker $workerId." +
" Asking it to re-register.")
worker.send(ReconnectWorker(masterUrl))
} else {
logWarning(s"Got heartbeat from unregistered worker $workerId." +
" This worker was never registered, so ignoring the heartbeat.")
}
}
}
Some:代表有值
None:代表没有值
private val idToWorker = new HashMap[String, WorkerInfo]
Some[+A](x: A) extends Option[A] with Product with Serializable
--Worker.scala
case SendHeartbeat =>
if (connected) { sendToMaster(Heartbeat(workerId, self)) }
--DeployMessage.scala
private[deploy] sealed trait DeployMessage extends Serializable
case class Heartbeat(workerId: String, worker: RpcEndpointRef) extends DeployMessage