zoukankan      html  css  js  c++  java
  • 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型

    一、前述

    Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。

    模式匹配机制相当于java中的switch-case。

    使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。

    Actor相当于Java中的多线程。

    二、具体阐述

    trait特性

         1、概念理解

    Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。

    与接口不同的是,它还可以定义属性和方法的实现。

    一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait

       2、举例:trait中带属性带方法实现

    • 继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
    • trait中不可以传参。
    trait Read {
      val readType = "Read"
      val gender = "m"
      def read(name:String){
    	println(name+" is reading")
      }
    }
    
    trait Listen {
      val listenType = "Listen"
      val gender = "m"
      def listen(name:String){
    	println(name + " is listenning")
      }
    }
    
    class Person() extends Read with Listen{
      override val gender = "f"
    }
    
    object test {
      def main(args: Array[String]): Unit = {
        val person = new Person()
        person.read("zhangsan")
        person.listen("lisi")
        println(person.listenType)
        println(person.readType)
        println(person.gender)
        
      }
    }
    

     

     3、举例:trait中带方法不实现

    object Lesson_Trait2 {
      def main(args: Array[String]): Unit = {
        val p1 = new Point(1,2)
        val p2 = new Point(1,3)
        println(p1.isEqule(p2))
        println(p1.isNotEqule(p2))
      }
    }
    
    trait Equle{
      def isEqule(x:Any) :Boolean 
      def isNotEqule(x : Any)  = {
        !isEqule(x)
      }
    }
    
    class Point(x:Int, y:Int) extends Equle {
      val xx = x
      val yy = y
    
      def isEqule(p:Any) = {
        p.isInstanceOf[Point] && p.asInstanceOf[Point].xx==xx
      }
      
    }
    

     模式匹配match

          1、概念理解:

             Scala 提供了强大的模式匹配机制,应用也非常广泛。

            一个模式匹配包含了一系列备选项,每个都开始于关键字 case

            每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。

     

         2、代码及注意点

    • 模式匹配不仅可以匹配值还可以匹配类型
    • 从上到下顺序匹配,如果匹配到则不再往下匹配
    • 都匹配不上时,会匹配到case _ ,相当于default
    • match 的最外面的”{ }”可以去掉看成一个语句
    object Lesson_Match {
      def main(args: Array[String]): Unit = {
        val tuple = Tuple6(1,2,3f,4,"abc",55d)
        val tupleIterator = tuple.productIterator
        while(tupleIterator.hasNext){
          matchTest(tupleIterator.next())
        }
        
      }
      /**
       * 注意点:
       * 1.模式匹配不仅可以匹配值,还可以匹配类型
       * 2.模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配
       * 3.模式匹配中,都匹配不上时,会匹配到 case _ ,相当于default
       */
      def matchTest(x:Any) ={
        x match {
          case x:Int=> println("type is Int")
          case 1 => println("result is 1")
          case 2 => println("result is 2")
          case 3=> println("result is 3")
          case 4 => println("result is 4")
          case x:String => println("type is String")
    //      case x :Double => println("type is Double")
          case _ => println("no match")
        }
      }
      
    }
    

     样例类(case classes)

    1、概念理解

         使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val),当构造参数是声明为var类型时,它帮你实现settergetter方法。

    • 样例类默认帮你实现了toString,equalscopyhashCode等方法。
    • 样例类可以new, 也可以不用new

    2、例子:结合模式匹配的代码

    case class Person1(name:String,age:Int)
    
    object Lesson_CaseClass {
      def main(args: Array[String]): Unit = {
        val p1 = new Person1("zhangsan",10)
        val p2 = Person1("lisi",20)
        val p3 = Person1("wangwu",30)
        
        val list = List(p1,p2,p3)
        list.foreach { x => {
          x match {
            case Person1("zhangsan",10) => println("zhangsan")
            case Person1("lisi",20) => println("lisi")
            case _ => println("no match")
          }
        } }
        
      }
    }
    

     Actor Model

    1、概念理解

    Actor Model是用来编写并行计算或分布式系统的高层次抽象(类似java中的Thread)让程序员不必为多线程模式下共享锁而烦恼,被用在Erlang 语言上, 高可用性99.9999999 % 一年只有31ms 宕机Actors将状态和行为封装在一个轻量的进程/线程中,但是不和其他Actors分享状态,每个Actors有自己的世界观,当需要和其他Actors交互时,通过发送事件和消息,发送是异步的,非堵塞的(fire-andforget),发送消息后不必等另外Actors回复,也不必暂停,每个Actors有自己的消息队列,进来的消息按先来后到排列,这就有很好的并发策略和可伸缩性,可以建立性能很好的事件驱动系统。

    Actor的特征:

    • ActorModel是消息传递模型,基本特征就是消息传递
    • 消息发送是异步的,非阻塞的
    • 消息一旦发送成功,不能修改
    • Actor之间传递时,自己决定决定去检查消息,而不是一直等待,是异步非阻塞的

    2、什么是Akka

    Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java Scala Actor 模型应用,底层实现就是Actor,Akka是一个开发库和运行环境,可以用于构建高并发、分布式、可容错、事件驱动的基于JVM的应用。使构建高并发的分布式应用更加容易。

    spark1.6版本之前,spark分布式节点之间的消息传递使用的就是Akka,底层也就是actor实现的。1.6之后使用的netty传输。

    3、例:Actor简单例子发送接收消息

    import scala.actors.Actor
    
    class myActor extends Actor{
      
      def act(){
        while(true){
          receive {
            case x:String => println("save String ="+ x)
            case x:Int => println("save Int")
            case _ => println("save default")
          }
        }
      }
    }
    
    object Lesson_Actor {
      def main(args: Array[String]): Unit = {
        
        //创建actor的消息接收和传递
        val actor =new myActor()
        //启动
        actor.start()
        //发送消息写法
        actor ! "i love you !"
    
      }
    }
    

     4、例:ActorActor之间通信

    case class Message(actor:Actor,msg:Any)
    
    class Actor1 extends Actor{
      def act(){
        while(true){
          receive{
            case  msg :Message => {
              println("i sava msg! = "+ msg.msg)
              
              msg.actor!"i love you too !"
              }
            case msg :String => println(msg)
            case  _ => println("default msg!")
          }
        }
      }
    }
    
    class Actor2(actor :Actor) extends Actor{
      actor ! Message(this,"i love you !")
    	def act(){
    		while(true){
    			receive{
      			case msg :String => {
      			  if(msg.equals("i love you too !")){
      			    println(msg)
      			   actor! "could we have a date !"
      			  }
      			}
      			case  _ => println("default msg!")
    			}
    		}
    	}
    }
    
    object Lesson_Actor2 {
      def main(args: Array[String]): Unit = {
        val actor1 = new Actor1()
        actor1.start()
        val actor2 = new Actor2(actor1)
        actor2.start()
      }
    }
    

     附例:WordCount

    import org.apache.spark.SparkConf
    import org.apache.spark.SparkContext
    import org.apache.spark.rdd.RDD
    import org.apache.spark.rdd.RDD.rddToPairRDDFunctions
    
    object WordCount {
      def main(args: Array[String]): Unit = {
        val conf = new SparkConf()
        conf.setMaster("local").setAppName("WC")
        val sc = new SparkContext(conf)
        val lines :RDD[String] = sc.textFile("./words.txt")
        val word :RDD[String]  = lines.flatMap{lines => {
          lines.split(" ")
        }}
        val pairs : RDD[(String,Int)] = word.map{ x => (x,1) }
        val result = pairs.reduceByKey{(a,b)=> {a+b}}
        result.sortBy(_._2,false).foreach(println)
        
        //简化写法
        lines.flatMap { _.split(" ")}.map { (_,1)}.reduceByKey(_+_).foreach(println)
        
      }
    }
    

     

     

  • 相关阅读:
    终于找到了一本PYTHON的中文书籍
    深圳测试协会第二次活动顺利举行
    Peer review
    如何在LINUX/UNIX上运行PYTHON程序
    CMMI各级关注的过程域(原创)
    深圳测试协会第三次活动顺利结束
    深圳测试沙龙第二期活动园满结束
    51testing软件测试沙龙
    sql中使用游标
    关于Asp.net 页面动态加载用户控件,出现“未能加载视图状态”的原因[续]
  • 原文地址:https://www.cnblogs.com/LHWorldBlog/p/8400689.html
Copyright © 2011-2022 走看看