日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

重游scala04

發(fā)布時間:2024/2/28 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重游scala04 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Scala編程

?

?

課程大綱

課程內(nèi)容

學(xué)習(xí)效果

掌握目標

Scala編程數(shù)據(jù)結(jié)構(gòu)

Scala類、對象

掌握

熟練掌握類的定義,創(chuàng)建對象

熟練掌握繼承和特質(zhì)

熟練掌握樣例類、模式匹配

?

Scala繼承

掌握

Scala特質(zhì)

掌握

Scala樣例類

掌握

Scala模式匹配

掌握

?

?

Scala的類與Java、C++的類比起來更簡潔,學(xué)完之后你會更愛Scala!!!

一、類

1、類的定義

Scala 訪問修飾符有:private,protected,public。

//在Scala中,類的定義可以通過class關(guān)鍵字實現(xiàn),類并不用聲明為public。

//Scala源文件中可以包含多個類,所有這些類都具有公有可見性。

class Dog {

??//屬性必須有初始值,如果不想有初始值初始化為_下劃線,賦值為_是必須指定數(shù)據(jù)類型

??private var?leg = 4

??def shout(content: String) {

????println(content)

??}

??def currentLeg = leg

}

?

使用這個類:

//在Scala中,類并不用聲明為public。默認就是public

val dog = new Dog

//調(diào)用方法,通過對象.方法 對象+空格+方法

dog shout "汪汪汪"

dog.shout("汪汪汪")

println(dog currentLeg)

println(dog.currentLeg)

//訪問屬性,通過對象.屬性 對象+空格+屬性

dog.leg = 4

println(“l(fā)eg = “+dog.leg)

dog leg = 4

println(dog leg)

?

//在Scala中,類并不用聲明為public。

//Scala源文件中可以包含多個類,所有這些類都具有公有可見性。

class Person {

??//用val修飾的變量是只讀屬性,有g(shù)etter但沒有setter

??//(字面量,相當與Java中用final修飾的變量)

??val id?= "9527"

??//用var修飾的變量既有g(shù)etter又有setter

??var age: Int = 18

// _代表初始值,使用時屬性必須指定類型

var color:Strng =?_

??//類私有字段,只能在伴生對象和類的內(nèi)部使用

??private var name: String = "唐伯虎"

??//對象私有字段,訪問權(quán)限更加嚴格的,當前對象的字段只能被Person類的方法訪問到

//對象私有字段,只能在類的內(nèi)部使用
??private[this] val pet = "小強"

}

?

尖叫提示:在Scala中,類并不聲明為Public,一個Scala源文件可以包含多個類。所有這些類都具有公有可見性。調(diào)用無參方法時,可以加(),也可以不加;如果方法定義不帶括號,那么調(diào)用時就不能帶括號

2、Getter?Setter方法

對于scala類中的每一個屬性,編譯后,會有一個私有的字段和相應(yīng)的getter、setter方法生成:

//getter

println(dog leg)

//setter

//對象.屬性_=(值)

dog.leg_=(10)

println(dog currentLeg)

當然了,你也可以不使用自動生成的方式,自己定義getter和setter方法

class Dog2 {

??private var _leg = 4

??def leg = _leg

??def leg_=(newLeg: Int) {

????_leg = newLeg

??}

}

使用之:

val dog2 = new Dog2

dog2.leg_=(10)

println(dog2.leg)

?

尖叫提示:自己手動創(chuàng)建變量的getter和setter方法需要遵循以下原則:

1) 字段屬性名以“_”作為前綴,如:_leg

2)?getter方法定義為:def leg = _leg

3) setter方法定義時,方法名為屬性名去掉前綴,并加上后綴,后綴是:“l(fā)eg_=”,如例子所示

?

3、Bean屬性

JavaBeans規(guī)范定義了Java的屬性是像getXXX()和setXXX()的方法。許多Java工具都依賴這個命名習(xí)慣。為了Java的互操作性。將Scala字段加@BeanProperty時,這樣的方法會自動生成。

創(chuàng)建一個Bean,使用@BeanProperty注解標識某個屬性變量

import scala.beans.BeanProperty

class Person {

??@BeanProperty var name: String = _

}

使用@BeanProperty注解標識的屬性只能以字母開頭,不能下劃線開頭。

?

通過getName、setName訪問屬性

val person = new Person

person.setName("Nick")

person.getName

println(person.name)

尖叫提示:

Person將會生成四個方法:

--name:String

--name_=(newValue:String): Unit

--getName():String

--setName(newValue:String):Unit

?

?

4、構(gòu)造器

scala中構(gòu)造分為主構(gòu)造器和輔助構(gòu)造器

注意:主構(gòu)造器會執(zhí)行類定義中的所有語句

/**

??*每個類都有主構(gòu)造器,主構(gòu)造器的參數(shù)直接放置類名后面,與類交織在一起

??*/

class Student(val name: String, val age: Int){

??//主構(gòu)造器會執(zhí)行類定義中的所有語句

??println("執(zhí)行主構(gòu)造器")

?

??private var gender = "male"

??//用this關(guān)鍵字定義輔助構(gòu)造器
??def this(name: String, age: Int, gender: String){
????//每個輔助構(gòu)造器必須以主構(gòu)造器或其他的輔助構(gòu)造器的調(diào)用開始

this(name, age)
????println("執(zhí)行輔助構(gòu)造器")
????this.gender = gender
??}

}

?

//主構(gòu)造器中name屬性沒有初始值,age屬性有初始值,那么在調(diào)用主構(gòu)造創(chuàng)建對象是,可以不傳age這個參數(shù)的值

class?Teacher(var name:String,var age:Int=30) {

}

//如果在主構(gòu)造器中屬性有初始值,那么在調(diào)用主構(gòu)造創(chuàng)建對象是,可以不傳這個參數(shù)的值

val?t01 = new Teacher("xiaoming")
println(" t01 name "+t01.name)
println("t01 age = "+t01.age)

?

?

尖叫提示:

(1)如果在主構(gòu)造器中定義的參數(shù)不帶val或var,這定義的參數(shù)不是類的屬性,不能通過“對象.參數(shù)名稱”?調(diào)用;

(2)如果在主構(gòu)造器中定義的參帶val或var,這定義的參數(shù)提升為類的屬性,能通過“對象.參數(shù)名稱”?調(diào)用;

(3)如果構(gòu)造器參數(shù)不帶val或var,但是參數(shù)被一個方法所使用,那么它將會被提升為類的屬性。

?

?

Scala 中的 private 限定符,比 Java 更嚴格,在嵌套類情況下,外層類甚至不能訪問被嵌套類的私有成員。

用 private 關(guān)鍵字修飾,帶有此標記的成員僅在包含了成員定義的類或?qū)ο髢?nèi)部可見,同樣的規(guī)則還適用內(nèi)部類。

?

?

?

  • 對象

1、對象

Object定義的結(jié)構(gòu)中的屬性和方法,是靜態(tài)的。存放工具方法和常量,即靜態(tài)的方法和屬性。

?

object Constants{
??val path = "aaaaa"
}
object StringUtil{
??def concat(a:String, b:String)= a+b
}

2、伴生對象

在Scala的類中,與類名相同的對象叫做伴生對象。利用伴生對象,可以實現(xiàn)單例。

//類A后面加了private,那么主構(gòu)造器就變?yōu)樗接辛?#xff0c;外部不能new實例
class A private{
??println("我是類")
}
object A{
??//但是伴生對象可以調(diào)用私有的主構(gòu)造器
??println("我是伴生對象"+new A())
}

?

//以下代碼實現(xiàn)單例
class SingleTon private{
??println("我是類")
}
object SingleTon{
??private val _instance = new SingleTon
??def instance = _instance
}

?

伴生類和伴生對象之間可以相互訪問私有的方法和屬性。也就是說,伴生類和伴生對象之間不受private限制。

package cn.bigdata.scala

class Dog {
??val id = 1
??private var name = "bigdata"

??def printName(): Unit ={
????//在Dog類中可以訪問伴生對象Dog的私有屬性
????println(Dog.CONSTANT + name )
??}
}

/**
??* 伴生對象
??*/
object Dog {

??//伴生對象中的私有屬性
??private val CONSTANT = "汪汪汪 : "

??def main(args: Array[String]) {
????val p = new Dog
????//訪問私有的字段name
????p.name = "123"
????p.printName()
??}
}

?

3、apply方法

通常我們會在類的伴生對象中定義apply方法。

object Teacher {
??println("我是對象Teacher")
??//調(diào)用Teacher()時,apply()方法會被調(diào)用
??def apply() = {println("我是apply()")}
}

?

?

?

?

一般,在伴生對象中會寫apply()方法,用于創(chuàng)建伴生類的實例。

當遇到類名(參數(shù)1,...參數(shù)n)時apply方法會被調(diào)用

package cn.bigdata.scala


object ApplyDemo {

??def main(args: Array[String]) {

//調(diào)用了Array伴生對象的apply方法

//def apply(x: Int, xs: Int*): Array[Int]

//arr1中只有一個元素5
????val arr1 = Array(5)
????println(arr1.toBuffer)

????//new了一個長度為5的array,數(shù)組里面包含5個null
????var arr2 = new Array(5)
??}
}

?

class?Dog(name:String) {
??var age:Int = 0
??def this(name:String,age:Int){
????this(name)
????this.age = age
??}
}
object Dog{
??def apply(name: String): Dog ={
????println("一個參數(shù)的apply");
????new Dog(name)
??}
??def apply(name: String,age:Int):Dog={
????println("兩個參數(shù)的apply");
????new Dog(name,age)
??}

??def main(args: Array[String]): Unit = {
????var a1 = Dog

//通過一個參數(shù)的apply創(chuàng)建對象,Dog會變成斜體
????var a2= ?Dog("lisi")

//通過兩個參數(shù)的apply創(chuàng)建對象
????var a3 = Dog("lisi",23)
??}
}

?

class Cat(var name:String, var age:Int) {
???var sex:Char = 'c'
???def this(name:String,age:Int,sex:Char){
????this(name,age)
????this.sex = sex
??}
}

object Cat{
??def apply(name:String,age:Int) = {
????println("這是伴生對象的兩個參數(shù)apply方法")
????new Cat(name,age)
??}
??def apply(name:String,age:Int,sex:Char)={
????println("這是伴生對象的三個參數(shù)apply方法")
????new Cat(name,age,sex)
??}
??def main(args: Array[String]): Unit = {
????var cat01 = new Cat("bosimao",1)
????var cat02 = Cat("bosimao",1)
????var cat03 = new Cat("bosimao",2,'1')
????var cat04 = Cat("bosimao",2,'1')
??}
}

?

4、應(yīng)用程序?qū)ο?/strong>

Scala程序都必須從一個對象的main方法開始,可以通過擴展App特質(zhì),不寫main方法。

?

package cn.bigdata.scala

object AppObjectDemo extends App{
??//不用寫main方法
??println("I love you Scala")
}

?

  • 繼承

1、繼承類

在Scala中擴展類的方式和Java一樣都是使用extends關(guān)鍵字

scala中不支持多繼承。

?

和Java一樣使用extends關(guān)鍵字,在定義中給出子類需要而超類沒有的字段和方法,或者重寫超類的方法。

?

class?Person ?{

??var?name = ""

}

?

class?Employee extends?Person{

??var?salary = 0.0

??def?description = "員工姓名:" + name + " 薪水:" + salary

}

尖叫提示:如果類聲明為final,他將不能被繼承。如果單個方法聲明為final,將不能被重寫。

2、類型檢查和轉(zhuǎn)換

Scala

Java

含義

obj.isInstanceOf[C]

obj instanceof C

判斷obj是不是C類型,返回boolean的值

obj.asInstanceOf[C]

(C)obj

將obj強制轉(zhuǎn)換成C類型,返回類實例

classOf[C]

C.class

返回class

?

?val a1 = new A1
?//返回true
?println(a1.isInstanceOf[A1])
?//返回false
println(a1.isInstanceOf[List[Int]])
?//返回class day031$A1
?println(a1.asInstanceOf[A].getClass)
?//報錯java.lang.ClassCastException: day031$A1 cannot be cast to scala.collection.immutable.List
?println(a1.asInstanceOf[List[Int]].size)

?

//返回class day031$A1
println(classOf[A1])
//返回class day031$A1
println(a1.getClass)

?

3、重寫方法

在Scala中重寫一個非抽象的方法必須使用override修飾符,調(diào)用超類的方法使用super關(guān)鍵字

class?Person {
??var name = ""
??override def toString = getClass.getName + "[name=" + name + "]"
}

class Employee extends Person {
??var salary = 0.0
??override def toString = super.toString + "[salary=" + salary + "]"
}

?

?

4、超類的構(gòu)造

輔助構(gòu)造器會調(diào)用主構(gòu)造器,主構(gòu)造器可以調(diào)用超類的構(gòu)造器。

class?Person(val name: String, val age: Int) {
??override def toString = getClass.getName + "[name=" + name +
????",age=" + age + "]"
}
class Employee(name: String, age: Int, val salary : Double) extends Person(name, age) {
??override def toString = super.toString + "[salary=" + salary + "]"
}

輔助構(gòu)造器永遠都不可能直接調(diào)用超類的構(gòu)造器,所以你不能調(diào)用super(params)因為supre用在輔助構(gòu)造器中。

5、重名字段

子類改寫父類或者抽象父類的字段,通過以下方式:

??class A{
????val name:String = "張三"
????def sleep() = "8 hours" ??//這是無參的方法
??}
??class A1 extends A{
????override val name="歷史"

????override val sleep: String = {"9 hours"} ?//這里理解為屬性
??}

??val a = new A()
??println(a.name)
??println(a.sleep)
??val a1 = new A1()
??println(a1.name)
??println(a1.sleep)
// ?println(a1.sleep()) //編譯錯誤

尖叫提示:

1、val屬性只能重寫另一個val屬性參的def同名方法

2、var不能重寫var屬性,但能重寫抽象的var屬性

6、抽象類

可以通過abstract關(guān)鍵字標記不能被實例化的類。

在抽象類中,沒有方法體的方法是抽象方法。沒有初始值的屬性是抽象屬性。

abstract class A{
??var name:String //抽象屬性
??def desc:String //抽象方法
}

class A1 extends A{
??//實現(xiàn)屬性,可以不加override,也可以加
??override var name: String = "zhangsan"
??//實現(xiàn)方法,可以不加override,也可以加
??override def desc: String = "aaaaaaaa"
}

val a1 = new A1()
println(a1.name)
println(a1.desc)

?

?

  • 特質(zhì)
  • 1)不允許多重繼承

    所有的面向?qū)ο蟮恼Z言都不允許直接的多重繼承,因為會出現(xiàn)“deadly diamond of death”問題。Scala提供了trait(特質(zhì)),特質(zhì)可以同時擁有抽象方法和具體方法,一個類可以實現(xiàn)多個特質(zhì)。

    2)當做接口使用的特質(zhì)

    特質(zhì)中沒有實現(xiàn)的方法就是抽象方法。類通過extends繼承特質(zhì),通過with可以繼承多個特質(zhì)。

    trait?Logger {
    ??def log(msg: String)
    }

    class ConsoleLogger extends Logger with Cloneable with Serializable {
    ??def log(msg: String) {
    ????println(msg)
    ??}
    }

    Logger with Cloneable with Serializable是一個整體,extends這個整體

    所有的java接口都可以當做Scala特質(zhì)使用。

    3帶有具體實現(xiàn)的特質(zhì)

    特質(zhì)中的方法并不一定是抽象的:

    trait?ConsoleLogger {
    ??def log(msg: String) {
    ????println(msg)
    ??}
    }

    class Account {
    ??protected var balance = 0.0
    }

    class SavingsAccount extends Account with ConsoleLogger {
    ??def withdraw(amount: Double) {
    ????if (amount > balance) log("余額不足")
    ????else balance -= amount
    ??}
    }

    ?

    ?

    ?

    //這是一個接口

    trait?Animal {

    //定義一個抽象方法
    ??def sleep

    //定義一個實現(xiàn)的方法,普通方法
    ??def eat(): Unit ={
    ????println("這是接口中的一個方法,已經(jīng)實現(xiàn)")
    ??}
    }

    ?

    //定義一個類去繼承接口,使用關(guān)鍵字extends

    class?Emp extends Animal{

    ??//實現(xiàn)它的抽象方法,關(guān)鍵字override 可有可無
    ??override def sleep: Unit = {
    ????println("繼承接口,并實現(xiàn)抽象方法")
    ??}

    ??//重寫已經(jīng)實現(xiàn)的方法,關(guān)鍵字override 必須有

    ??override def eat(): Unit = {
    ????println("繼承接口,并重寫已經(jīng)實現(xiàn)的方法")
    ??}
    }

    ?

    // extends 繼承一個類/抽象類 ?with 實現(xiàn)接口
    // 實現(xiàn)多個接口:with 接口1 with 接口2
    class Student extends Human with Animal with Flyable{
    ??override def work: Unit = {
    ????println("繼承抽象類,并實現(xiàn)抽象方法")
    ??}
    ??override def sleep: Unit = {
    ????println("實現(xiàn)接口,并實現(xiàn)抽象方法")
    ??}
    }

    ?

  • 為實例混入特質(zhì)
  • 在創(chuàng)建類的實例時,可以指定某個實例混入特質(zhì)。那么,只有這個實例有特質(zhì),其他實例沒有。

    trait Logger{
    ??def log(msg:String)=println("日志 "+msg)
    }
    class A{}
    class A1 extends A ?{
    }

    val a1 = new A1()
    println(a1)
    //實例a2混入特質(zhì),有l(wèi)og方法;a1沒有
    val a2 = new A1() with Logger
    a2.log("aaaaaaaaa")

    ?

  • 特質(zhì)調(diào)用鏈
  • 如果類繼承多個特質(zhì),那么特質(zhì)中的方法會依次執(zhí)行,類似于責任者模式。

    需要讓特質(zhì)中的方法最后調(diào)用super。

    trait Logger{
    ??def log(msg:String)=println("Logger日志 "+msg)
    }
    trait FileLogger extends Logger {
    ??override def log(msg: String): Unit = {
    ????println("FileLogger日志 "+msg)
    ????//必須調(diào)用super
    ????super.log(msg)
    ??}
    }
    trait HDFSLogger extends FileLogger {
    ??override def log(msg: String): Unit = {
    ????println("HDFSLogger日志 "+msg)
    ????//必須調(diào)用super
    ????super.log(msg)
    ??}
    }

    class A{}
    val a2 = new A() with Logger with FileLogger with HDFSLogger
    //從右向左,依次調(diào)用各個特質(zhì)中的log方法
    a2.log("aaaaaaaaa")

    ?

    ?

    ?

    四、模式匹配和樣例類

    Scala有一個十分強大的模式匹配機制,可以應(yīng)用到很多場合:如switch?case語句、類型檢查等。Java中的switch是按照類型判斷的,這里的模式匹配則可以不限制類型,功能更加強大。

    1、匹配

    與default等效的是捕獲所有的case_ 模式。如果沒有模式匹配,拋出MatchError,每個case中,不用break語句。可以在match中使用任何類型可以是字符串也可以是數(shù)字,而不僅僅是數(shù)字。

    package cn.bigdata.cases
    import scala.util.Random

    object CaseDemo01 extends App{
    ??val arr = Array("a", "b", "c")
    ??val name = arr(Random.nextInt(arr.length))

    ??//匹配到case 后面的值,就執(zhí)行=> 后面的內(nèi)容
    ??//沒有匹配到就 匹配_, 執(zhí)行 => 后面的內(nèi)容

    ??name match {
    ????case "a" => println("aa...")
    ????case "b" => println("bb...")
    ????case _ => println("真不知道你們在說什么...")
    ??}
    }

    尖叫提示:如果把case _作為第一個case,則永遠匹配 case _

    ??????????如果沒有case_ ,且match中沒有匹配的case,則會拋出異常,scala.MatchError

    //模式匹配結(jié)果作為函數(shù)返回值
    def patternShow(x : Any) = x match {
    ??case 5 => "五"
    ??case true => "真"
    ??case "test" => "字符串"
    ??case null => "null值"
    ??case Nil => "空列表"
    ??case _ => "其他常量"
    }
    println(patternShow(5))
    println(patternShow(true))
    println(patternShow(List()))

    ?

  • 匹配變量
  • 變量匹配,匹的是case語句后面接的是scala變量,如case x if(x == 5) => x等,在使用時一般會加守衛(wèi)條件,當然也可以像case x => x這樣使用,它會匹配任何輸入的合法變量。

    //模式匹配結(jié)果作為函數(shù)返回值
    def patternShow(x : Any) = x match {
    ??case x if (x == 5) => x
    ??case x if (x == "Scala") => x
    ??case _ =>
    }
    println(patternShow(5))
    println(patternShow("Scala"))

    ?

    ?

  • 匹配類型
  • 它可以匹配輸入待匹配變量的類型。

    object TypePattern{

      def main(args:Array[String]) :Unit = {

      def typePattern(t : Any) = t match {{

        case t : String => "String"

        case t : Int => "Intger"

        case t : Double => "Double"

        case _ => "Other Type"

      }

      println(typePattern(5.0))

      println(typePattern(5))

      println(typePattern("5"))

      println(typePattern(List()))

      }

    }

    4、匹配數(shù)組、列表、元組

    package cn.bigdata.cases

    object CaseDemo03 extends App{

    ??val arr = Array(1, 3, 5)
    ??arr match {
    ????case Array(1, x, y) => println(x + " " + y)
    ????case Array(0) => println("only 0")
    ????case Array(0, _*) => println("0 ...")
    ????case _ => println("something else")
    ??}

    //_ 表示一個元素的通配符

    //_*?表示0個或者多個元素的通配符

    ??val lst = List(3, -1)
    ??lst match {
    ????case 0 :: Nil => println("only 0")

    case?_ ::Nil => println("List 只有一個元素的List,這個元素是任意值")
    ????case x :: y :: Nil => println(s"x: $x?y: $y")
    ????case 0 :: tail => println("0 ...")
    ????case _ => println("something else")
    ??}

    ??val tup = (2, 3, 7)
    ??tup match {
    ????case (1, x, y) => println(s"1, $x?, $y")
    ????case (_, z, 5) => println(z)
    ????case ?_ => println("else")
    ??}

    //元組只能匹配內(nèi)容,固定長度的元組只能匹配對應(yīng)長度的元組,只是配置內(nèi)容,不能匹配長度
    }

    ?

    注意:在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。

    9 :: List(5, 2) ?:: 操作符是將給定的頭和尾創(chuàng)建一個新的列表

    注意:: 操作符是右結(jié)合的,如9 :: 5 :: 2 :: Nil相當于 9 :: (5 :: (2 :: Nil))

    五、異常

    當碰到異常情況時,方法拋出一個異常,終止方法本身的執(zhí)行,異常傳遞到其調(diào)用者,調(diào)用者可以處理該異常,也可以升級到它的調(diào)用者。運行系統(tǒng)會一直這樣升級異常,直到有調(diào)用者能處理它。 如果一直沒有處理,則終止整個程序。

    Scala的異常的工作機制和Java一樣,但是Scala沒有“checked”異常,你不需要聲明說函數(shù)或者方法可能會拋出某種異常。受檢異常在編譯器被檢查,java必須聲明方法所會拋出的異常類型。

    拋出異常:用throw關(guān)鍵字,拋出一個異常對象。所有異常都是Throwable的子類型。throw表達式是有類型的,就是Nothing,因為Nothing是所有類型的子類型,所以throw表達式可以用在需要類型的地方。

    捕捉異常:在Scala里,借用了模式匹配的思想來做異常的匹配,因此,在catch的代碼里,是一系列case字句。

    異常捕捉的機制與其他語言中一樣,如果有異常發(fā)生,catch字句是按次序捕捉的。因此,在catch字句中,越具體的異常越要靠前,越普遍的異常越靠后。 如果拋出的異常不在catch字句中,該異常則無法處理,會被升級到調(diào)用者處。

    finally字句用于執(zhí)行不管是正常處理還是有異常發(fā)生時都需要執(zhí)行的步驟,一般用于對象的清理工作。

    object?ExceptionSyllabus {

    ??def divider(x: Int, y: Int): Float= {
    ????if(y == 0) throw new Exception("0作為了除數(shù)")
    ????else x / y
    ??}

    ??def main(args: Array[String]): Unit = {
    ????try {
    ??????println(divider(10, 3))
    ????} catch {
    ??????case ex: Exception => println("捕獲了異常:" + ex)
    ????} finally {}
    ??}
    }

    ?

    ?

    、樣例類

    在Scala中樣例類是一中特殊的類case class,默認實現(xiàn)了Serializable。case class是多例的,后面要跟構(gòu)造參數(shù),case object是單例的。

    ?

    當你聲明了一個 case class,Scala 編譯器為你做了這些:

  • 創(chuàng)建 case class 和它的伴生 object
  • 實現(xiàn)了 apply 方法讓你不需要通過 new 來創(chuàng)建類實例
  • 默認為主構(gòu)造函數(shù)參數(shù)列表的所有參數(shù)前加 val
  • 添加天然的 hashCode、equals 和 toString 方法。由于 == 在 Scala 中總是代表 equals,所以 case class 實例總是可比較的
  • 生成一個 copy 方法以支持從實例 a 生成另一個實例 b,實例 b 可以指定構(gòu)造函數(shù)參數(shù)與 a 一致或不一致
  • ?

    case class A(id:Int, name:String, age:Int);
    //使用伴生對象創(chuàng)建實例
    val a = A(1,"張三", 23)
    //輸出A(1,張三,23)
    println(a)
    //已經(jīng)覆蓋copy方法
    val b = a.copy()
    //輸出A(1,張三,23)
    println(b)
    //輸出true
    println(a==b)

    ?

    Case class可以用于模式匹配。

    //定義樣例類
    case class Address(street: String, city: String, country: String)
    case class Person(name: String, age: Int, address: Address)
    //創(chuàng)建實例
    val alice = Person("Alice", 12, Address("1 hello world", "2 hello world", "CN"))
    val bob = Person("Bob", 12, Address("1 hello world", "2 hello world", "CN"))
    val charlie = Person("Charlie", 12, Address("1 hello world", "2 hello world", "CN"))

    for (person <- Seq(alice, bob, charlie)) {
    ??person match { ?//匹配實例值,使用==判斷
    ????case Person("Alice", 12, Address(_, "2 hello world", _)) => println("hi alice")
    ????case Person("Bob", 12, Address("1 hello world", "2 hello world", "CN")) => println("hi bob")
    ????case Person(name, age, _) => println("who are you?")
    ??}
    }

    ?

    超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達旦的技術(shù)人生

    總結(jié)

    以上是生活随笔為你收集整理的重游scala04的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。