• Scala实践10


    1、模式匹配

          模式匹配是一种根据模式检查值的机制。它是switch(Java中语句)的更强大版本,它同样可以用来代替一系列if / else语句。

    • 句法

    匹配表达式具有值,match关键字和至少一个case子句。

    import scala.util.Random
    
    val x: Int = Random.nextInt(10)
    
    x match {
      case 0 => "zero"
      case 1 => "one"
      case 2 => "two"
      case _ => "other"
    }

      val x上面是0和10之间的随机整数,x成为的左操作数match运算符和右边是与4箱子的表达式。最后一种情况(_)是任何其他可能Int值的“全部捕获”情况。案件也被称为替代品

    • 匹配案例类

    案例类对模式匹配特别有用。

    abstract class Notification//抽象超类
    
    case class Email(sender: String, title: String, body: String) extends Notification
    
    case class SMS(caller: String, message: String) extends Notification
    
    case class VoiceRecording(contactName: String, link: String) extends Notification
    

      Notification是具有与壳体的类实现的三个具体的通知类型的抽象超类EmailSMSVoiceRecording。现在我们可以对这些案例类进行模式匹配:

    def showNotification(notification: Notification): String = {
      notification match {
        case Email(sender, title, _) =>
          s"You got an email from $sender with title: $title"
        case SMS(number, message) =>
          s"You got an SMS from $number! Message: $message"
        case VoiceRecording(name, link) =>
          s"you received a Voice Recording from $name! Click the link to hear it: $link"
      }
    }
    val someSms = SMS("12345", "Are you there?")
    val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
    
    println(showNotification(someSmps))  
    
    println(showNotification(someVoiceRecording)) 
    

      该函数showNotification作为参数的抽象类型Notification和类型相匹配Notification(即,它计算出它是否是一个EmailSMSVoiceRecording)。在case Email(sender, title, _)字段中sender并且title在返回值中使用但是body忽略该字段_

    • 模式守护

    模式保护只是布尔表达式,用于使案例更具体。只需if <boolean expression>在模式后添加。

    def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = {
      notification match {
        case Email(sender, _, _) if importantPeopleInfo.contains(sender) =>
          "You got an email from special someone!"
        case SMS(number, _) if importantPeopleInfo.contains(number) =>
          "You got an SMS from special someone!"
        case other =>
          showNotification(other) 
      }
    }
    
    val importantPeopleInfo = Seq("867-5309", "jenny@gmail.com")
    
    val someSms = SMS("867-5309", "Are you there?")
    val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
    val importantEmail = Email("jenny@gmail.com", "Drinks tonight?", "I'm free after 5!")
    val importantSms = SMS("867-5309", "I'm here! Where are you?")
    
    println(showImportantNotification(someSms, importantPeopleInfo))
    println(showImportantNotification(someVoiceRecording, importantPeopleInfo))
    println(showImportantNotification(importantEmail, importantPeopleInfo))
    println(showImportantNotification(importantSms, importantPeopleInfo))
    

      在图中case Email(sender, _, _) if importantPeopleInfo.contains(sender),只有sender在重要人物列表中才匹配模式。

    • 仅在类型上匹配
    abstract class Device
    case class Phone(model: String) extends Device{
      def screenOff = "Turning screen off"
    }
    case class Computer(model: String) extends Device {
      def screenSaverOn = "Turning screen saver on..."
    }
    
    def goIdle(device: Device) = device match {
      case p: Phone => p.screenOff
      case c: Computer => c.screenSaverOn
    }
    

      def goIdle具有不同的行为取决于类型Device。当案例需要在模式上调用方法时,这很有用。它是使用类型的情况下标识(第一个字母的公约pc在这种情况下)。

    • 密封课程

    可以标记特征和类sealed,这意味着必须在同一文件中声明所有子类型。这确保了所有亚型都是已知的。

    sealed abstract class Furniture
    case class Couch() extends Furniture
    case class Chair() extends Furniture
    
    def findPlaceToSit(piece: Furniture): String = piece match {
      case a: Couch => "Lie on the couch"
      case b: Chair => "Sit on the chair"
    }
    

      

    2、案例类

    • 定义案例类

    最小的案例类需要关键字case class,标识符和参数列表(可能为空):

    case class Book(isbn: String)
    
    val frankenstein = Book("912-0111182114")
    

      注意:实例化Book案例时没有new关键字。这是因为case类apply默认有一个方法来处理对象构造。

                     使用参数创建案例类时,参数是公共val的。

    case class Message(sender: String, recipient: String, body: String)
    val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "Ça va ?")
    
    println(message1.sender)  //合法的
    message1.sender = "travis@washington.us"  // 不合法的
    

      不能重新分配,message1.sender因为它是一个val(即不可变的)。

  • 相关阅读:
    个人冲刺8
    个人冲刺7
    个人冲刺6
    个人冲刺5
    个人冲刺4
    个人冲刺阶段3
    个人冲刺阶段2
    课下作业1-扩展阅读
    随手快递app开发的第四天
    随手快递app开发的第三天
  • 原文地址:https://www.cnblogs.com/0205gt/p/11046407.html
Copyright © 2020-2023  润新知