Scala類與模式匹配

Scala 官網:http://www.scala-lang.org/

一、類

1、main

/*
 * main method
 * ⑴如同Java中,如果要運行一個程序,必須編寫一個包含main方法的類一樣;
 * 在Scala中,如果要運行一個應用程序,必須要有一個main方法,作爲入口;
 * ⑵在Scala中的main方法定義爲def main(args:Array[String]),而且必須定義在object中;
 * ⑶運行下面的代碼,需要將其放入.scala文件中,然後先使用scalac編譯,再用scala執行;
 */
object HelloWorld {
  def main(args: Array[String]) {
    println("Hello World!!!")
  }
}


2、object

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/*
 * class and object
 * ⑴object相當於class的單個實例,通常在裏面放一些靜態的field或者method;
 * ⑵第一次調用object的方法時,就會執行object的constructor,也就是object內部不在method中的代碼;
 * 但是object不能定義接受參數的constructor;
 * ⑶object的constructor只會在其第一次被調用時執行一次,以後再次調用就不會再次執行constructor了;
 * ⑷object通常用於作爲單例模式的實現,或者放class的靜態成員,比如工具方法;
 * ⑸如果有一個class,還有一個與class同名的object,那麼就稱這個object是class的伴生對象,
 * class是object的伴生類;
 * ⑹伴生類和伴生對象必須存放在一個.scala文件之中;
 * ⑺伴生類和伴生對象,最大的特點就在於,相互可以訪問private field;
 */
object Person {
  private  val eyeNum = 2
  println("this is Person object!")
  def getEyeNum = eyeNum

  def main(args: Array[String]) {
    val person = new Person("hadoop",11)
    person.sayHello
  }
}

//當函數沒有參數時可以省略小括號,當函數體只有一句話時,可以省略花括號
class Person(val name:String, val age:Int){
  def sayHello = println("Hi, "
    + name
    + ", I guess you are "
    + age
    + " years old!"
    + ", and usually you must have "
    + Person.eyeNum
    + " eyes.")
}


3、apply

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴通常我們在伴生對象中定義apply方法,在方法中實現構造伴生類實例的功能;
 * ⑵apply方法的方法名稱必須使用apply;
 * ⑶apply方法的參數接受與class類主構造方法相同的參數,並返回該類的實例;
 */
class person1 {
  //定義屬性
  var name: String = ""

  //定義方法
  def wachTV(TVName: String) = {
    println(name + " is waching " + TVName + " with " + person1.eyeNm + " eyes ") //可以調用其伴生對象的私有屬性
  }
}

object person1 extends App {
  def apply() = {
    println("****apply function has been invoked!!*******")
    new person1()
  }

  private val eyeNm: Int = 2
  val p =person1()
  p.name = "Lili"
  p.wachTV("DongFang")
}


4、this

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴主構造器直接跟在類名後面,主構造器中的參數最後會被變異成字段、屬性;
 * ⑵主構造器執行時,會執行類中的所有語句;
 * ⑶假設參數聲明時不帶val或var,那麼相當於private[this],只能在內部使用;
 * @param name
 * @param age
 */
class Person2(var name: String, val age: Int) {
  //constructor
  val school: String = "bruce"
  var sex: String = ""
  //附屬構造器名稱爲this;
  def this(name: String, age: Int, sex: String) = {
    this(name, age)
    this.sex = sex
  }
}

object Person2 extends App {
  //調用主構造器
  val person = new Person2("tom", 21)
  println("name:" + person.name + ",age:" + person.age + ",school:" + person.school)
  //調用附屬構造器
  var person1=new Person2("mary",22,"male")
  println("name:" + person1.name + ",age:" + person1.age + ",school:" + person1.school+",sex:"+person1.sex)
}


5、exception

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * Scala異常處理:case匹配的方式處理(處理或者throw出去)
 */
object exception extends App{

  try {
    val a = 1 / 0
  }
  catch {
    case e: ArithmeticException => throw new RuntimeException("除數不能爲0") //匹配除數爲零
    case _ => println("other.......")  //匹配其他異常
  }
}


二、模式匹配

1、模式匹配-值

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴Scala是沒有Java中的switch case語法的,相對應的,Scala提供了更強大的match case語法,即模式匹配;
 * ⑵Scala的match case與Java的switch case最大的不同點在於,Java的switch case僅能匹配變量的值,比如1,2,a,b等;
 * 而Scala的match case可以匹配各種情況,比如變量的類型、集合的元素、有值或無值;
 * ⑶match case的語法如下:變量 match {case 值 => 代碼}。如果值爲下劃線,則代表了不滿足以上所有情況下的默認情況如何處理;
 * 此外,match case中,只要一個case分支滿足並處理了,就不會繼續判斷下一個case分支了。(與Java不同,Java的switch case需要用break阻止);
 * ⑷當然,match case語法最基本的應用,就是對變量的值進行模式匹配;
 */
object grade1 extends App {
  def judgeGrade(grade:String){
    grade match {
      case "A" => println("Excellent")
      case "B" => println("Good")
      case "C" => println("Just so so")
      case _ => println("You need work harder")
    }
  }
  judgeGrade("D")
}


package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴Scala的模式匹配語法,有一個特點在於,可以在case後的條件判斷中,不僅僅只是提供一個值,
 * 而是可以在值後面再加一個if守衛,進行雙重過濾;
 * ⑵Scala的模式匹配語法,可以將模式匹配的默認情況下劃線,替換爲一個變量名,
 * 此時模式匹配語法就會把將要匹配的值賦值給這個變量,從而可以在後面的處理語句中使用要匹配的值;
 */
object grade2 extends App{
  def judgeGrade(name:String, grade:String){
    grade match {
      case "A" => println(name+ ",you are excellent")
      case "B" => println(name+ ",you are good")
      case "C" => println(name+ ",you are just so so")
      case _grade if name == "bruce" => println(name+", your grade is "+ _grade)
      case _grade => println("You need work harder,your grade is "+ _grade)
    }
  }
  judgeGrade("bruce","D")
}


2、模式匹配-類型

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴Scala的模式匹配一個強大之處就在於,可以直接匹配類型,而不是值!!!
 * ⑵對類型如何進行匹配?其他語法與匹配值其實是一樣的,但是匹配類型的話,就是要用
 * case 變量:類型 => 代碼
 */
object matchType extends App{
  def judgeType(x:Any)={
    x match {
      case x:Int => println("Int........")
      case x:String => println("String........")
      case x:Double => println("Double........")
      case _ => println("other........")
    }
  }
  judgeType("aa")
}


3、模式匹配-array、list

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴對Array進行模式匹配,分別可以匹配帶有指定元素的數組、帶有指定個數元素的數組、以某元素打頭的數組;
 * ⑵對List進行模式匹配,與Array類似,但是需要使用List特有的::操作符;
 */
object matchArray extends App{
  def greeting(arr: Array[String]) = {
    arr match {
      case Array("Hadoop") => println("hi ,Hadoop !") //匹配帶有指定元素的數組
      case Array("Hadoop",_*)=>println("hi,Hadoop,please introduce your friends to me ")//以某元素打頭的數組
      case Array(a,b,c) => println(a+","+b+","+c+",there are 3 students !!") //帶有指定個數元素的數組
      case _ => println("other........")
    }
  }

  def greet(list: List[String]) = {
    list match {
      case "Hadoop"::Nil => println("hi ,Hadoop !") //匹配帶有指定元素的數組
      case "Hadoop"::tail => println("hi,Hadoop,please introduce your friends to me ") //以某元素打頭的數組
      case a::b::c::Nil => println(a + "," + b + "," + c + ",there are 3 students !!") //帶有指定個數元素的數組
      case _ => println("other........")
    }
  }
  greeting(Array("Hive","Hadoop","Scala"))
  println("*********************************************")
  greet(List("Hive","Hadoop","Scala"))
}



4、模式匹配-tuple

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * 對tuple元組的元素情況匹配
 */
object matchTuple extends App{
  def match_tuple(tuple:Any) ={
    tuple match {
      case (0,_) => println("the first is 0")
      case (a,0,_) => println("the second is 0  "+a)
      case _ => println("other.....")
    }
  }

  match_tuple(0,"Scala")
  match_tuple(2,0,1)
  match_tuple((0,0,3))
}


5、模式匹配-class

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴Scala中提供了一種特殊的類,用case class進行聲明,中文也可以稱作樣例類;
 * case class其實有點類似於Java中的JavaBean的概念;
 * 即只定義field,並且由Scala編譯時自動提供getter和setter方法,但是沒有method;
 * ⑵case class的主構造函數接收的參數通常不需要使用var或val修飾,Scala自動就會使用val修飾;
 * Scala自動爲case class定義了伴生對象,也就是object,並且定義了apply()方法,
 * 該方法接收主構造函數中相同的參數,並返回case class對象;
 */
case class Teacher(name: String, subject: String)
case class Student(name: String, classRoom: String)
class PP()
class matchClass{
  def judgeID(p: Any) = {
    p match {
      case Teacher(name, subject) => println("name:" + name + ",subject:" + subject)
      case Student(name, classRoom) => println("name:" + name + ",classRoom:" + classRoom)
      case _ => println("who are you !!")
    }
  }
}
object matchClass extends App{
  val p = new matchClass
  p.judgeID(new PP())
  p.judgeID(Teacher("bruce","Scala"))	 //因爲我們聲明的Teacher爲case class類,所以不需要使用new
}



6、模式匹配-option

package com.example.scala

/**
 * Created by Bruce on 2017/6/12.
 */
/**
 * ⑴Scala有一種特殊的類型,叫做Option,Option有兩種值,一種是Some,表示有值,一種是None,表示沒有值;
 * ⑵Option通常會用於模式匹配中,用於判斷某個變量是否有值,比null更加簡潔明瞭;
 * ⑶Spark源碼中大量的使用了Option,比如Some(a)、None這種語法,因此看得懂Option模式匹配,才能夠讀懂spark源碼;
 */
object matchOption extends App{

  val grades=Map("Scala"->"A","Hadoop"->"C","Spark"->"B")

  def getGrade(name:String)={
    val grade=grades.get(name)
    grade match {
      case Some(grade1)=>println("your grade is "+ grade1)
      case None =>println("your grade is not in this system!")
    }
  }
  getGrade("Spark")
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章